package api

import (
	"net/http"
	"testing"

	"github.com/gofiber/fiber/v2"
)

func TestPinProtectedEndpoints_Definition(t *testing.T) {
	seen := map[string]struct{}{}
	for _, ep := range PinProtectedEndpoints {
		if ep.Method == "" || ep.Path == "" || ep.Action == "" {
			t.Fatalf("invalid pin-protected endpoint: %#v", ep)
		}
		key := ep.Method + " " + ep.Path
		if _, ok := seen[key]; ok {
			t.Fatalf("duplicate pin-protected endpoint %s", key)
		}
		seen[key] = struct{}{}
	}
}

func TestPinProtectedEndpoints_RoutesHavePinMiddleware(t *testing.T) {
	if len(PinProtectedEndpoints) == 0 {
		return
	}
	app := fiber.New()
	RegisterRoutes(app, buildRouteDependenciesForTest())

	routes := app.GetRoutes(true)
	for _, ep := range PinProtectedEndpoints {
		route := findRoute(routes, ep.Method, ep.Path)
		if route == nil {
			t.Fatalf("pin-protected route %s %s is not registered", ep.Method, ep.Path)
		}
		minHandlers := 3 // pin + permission + handler
		if ep.Path == "/api/v1/auth/invite" {
			minHandlers = 4 // auth + pin + permission + handler (no group auth middleware)
		}
		if len(route.Handlers) < minHandlers {
			t.Fatalf("route %s %s expected at least %d handlers, got %d", ep.Method, ep.Path, minHandlers, len(route.Handlers))
		}
	}
}

func findRoute(routes []fiber.Route, method, path string) *fiber.Route {
	for i := range routes {
		if routes[i].Method == method && routes[i].Path == path {
			return &routes[i]
		}
	}
	return nil
}

func TestPinProtectedEndpoints_ExpectedMethods(t *testing.T) {
	for _, ep := range PinProtectedEndpoints {
		switch ep.Method {
		case http.MethodGet, http.MethodPost, http.MethodPatch, http.MethodDelete:
		default:
			t.Fatalf("unexpected method %q on pin-protected endpoint %s", ep.Method, ep.Path)
		}
	}
}
