package wrapngo

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/cenkalti/backoff/v4"
	"github.com/packethost/packngo"
	"k8s.io/klog/v2"
)

// wrap a given fn in some reliability-increasing duct tape: context support and
// exponential backoff retries for intermittent connectivity issues. This allows
// us to use packngo code instead of writing our own API stub for Equinix Metal.
//
// The given fn will be retried until it returns a 'permanent' Equinix error (see
// isPermanentEquinixError) or the given context expires. Additionally, fn will
// be called with a brand new packngo client tied to the context of the wrap
// call. Finally, the given client will also have some logging middleware
// attached to it which can be activated by setting verbosity 5 (or greater) on
// this file.
//
// The wrapped fn can be either just a plain packngo method or some complicated
// idempotent logic, as long as it cooperates with the above contract.
func wrap[U any](ctx context.Context, cl *client, fn func(*packngo.Client) (U, error)) (U, error) {
	var zero U
	if err := cl.serializer.up(ctx); err != nil {
		return zero, err
	}
	defer cl.serializer.down()

	bc := backoff.WithContext(cl.o.BackOff(), ctx)
	pngo, err := cl.clientForContext(ctx)
	if err != nil {
		// Generally this shouldn't happen other than with programming errors, so we
		// don't back this off.
		return zero, fmt.Errorf("could not crate equinix client: %w", err)
	}

	var res U
	err = backoff.Retry(func() error {
		res, err = fn(pngo)
		if isPermanentEquinixError(err) {
			return backoff.Permanent(err)
		}
		return err
	}, bc)
	if err != nil {
		return zero, err
	}
	return res, nil
}

type injectContextRoundTripper struct {
	ctx      context.Context
	original http.RoundTripper
	metrics  *metricsSet
}

func (r *injectContextRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	klog.V(5).Infof("Request -> %v", req.URL.String())
	start := time.Now()
	res, err := r.original.RoundTrip(req.WithContext(r.ctx))
	latency := time.Since(start)
	r.metrics.onAPIRequestDone(req, res, err, latency)

	if err != nil {
		klog.V(5).Infof("HTTP error <- %v", err)
	} else {
		klog.V(5).Infof("Response <- %v", res.Status)
	}
	return res, err
}

func (c *client) clientForContext(ctx context.Context) (*packngo.Client, error) {
	httpcl := &http.Client{
		Transport: &injectContextRoundTripper{
			ctx:      ctx,
			original: http.DefaultTransport,
			metrics:  c.metrics,
		},
	}
	return packngo.NewClient(packngo.WithAuth(c.username, c.token), packngo.WithHTTPClient(httpcl))
}

// httpStatusCode extracts the status code from error values returned by
// packngo methods.
func httpStatusCode(err error) int {
	var er *packngo.ErrorResponse
	if err != nil && errors.As(err, &er) {
		return er.Response.StatusCode
	}
	return -1
}

// IsNotFound returns true if the given error is an Equinix packngo/wrapngo 'not
// found' error.
func IsNotFound(err error) bool {
	return httpStatusCode(err) == http.StatusNotFound
}

func isPermanentEquinixError(err error) bool {
	// Invalid argument/state errors from wrapping.
	if errors.Is(err, ErrRaceLost) {
		return true
	}
	if errors.Is(err, ErrNoReservationProvided) {
		return true
	}
	// Real errors returned from equinix.
	st := httpStatusCode(err)
	switch st {
	case http.StatusUnauthorized:
		return true
	case http.StatusForbidden:
		return true
	case http.StatusNotFound:
		return true
	case http.StatusUnprocessableEntity:
		return true
	}
	return false
}
