package handler

import (
	"sync"
	"testing"

	"github.com/hashicorp/go-multierror"
	"github.com/labstack/echo/v4"

	"github.com/pingcap/test-infra/common/model"
	mw "github.com/pingcap/test-infra/services/tcms/handler/middleware"
	"github.com/pingcap/test-infra/services/tcms/tests"
	"github.com/pingcap/test-infra/services/tcms/tests/configtest"
	"github.com/pingcap/test-infra/services/tcms/utils"
)

func setup(t *testing.T, opts ...configtest.Option) *HTTPHandler {
	cfg := configtest.NewTestConfig(t, opts...)
	tests.Setup(t, cfg)
	svc := NewHandlerService(cfg.Config)

	// Deprecated: Use httptest.WithUser instead.
	setupAuthMW.Do(func() {
		authMW = mw.Auth(cfg.JWTKey, svc.Token.Validate)
	})

	h := NewHTTPHandler(*cfg.Config, svc)
	// drop db if success
	origShutdown := h.service.Shutdown
	h.service.Shutdown = func() (errs error) {
		if err := origShutdown(); err != nil {
			multierror.Append(errs, err)
		}
		succeed := !t.Failed()
		if succeed {
			if err := tests.DropDB(cfg.DSN); err != nil {
				multierror.Append(errs, err)
			}
		}
		return
	}
	return h
}

func genJWT(userID model.ID) string {
	return utils.JWTClaims{
		User: utils.SessionUser{
			ID: userID,
		},
	}.Encode(configtest.NewTestConfig(&testing.T{}).JWTKey)
}

var authMW echo.MiddlewareFunc
var setupAuthMW sync.Once

// Deprecated: Use httptest.WithUser instead.
func WithAuth(ctx echo.Context, f echo.HandlerFunc, userID ...model.ID) error {
	if len(userID) > 0 {
		ctx.Request().Header.Set(echo.HeaderAuthorization, "Bearer "+genJWT(userID[0]))
	}
	return authMW(func(context echo.Context) error {
		return f(ctx)
	})(ctx)

}
