package api

import (
	"net/http"
	"testing"

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

func TestRegisterRoutes(t *testing.T) {
	app := fiber.New()
	RegisterRoutes(app, buildRouteDependenciesForTest())

	routes := app.GetRoutes(true)
	required := []struct {
		method string
		path   string
	}{
		{method: http.MethodGet, path: "/health"},
		{method: http.MethodGet, path: "/version"},
		{method: http.MethodGet, path: "/api/version"},
		{method: http.MethodGet, path: "/api/build-info"},
		{method: http.MethodGet, path: "/metrics"},
		{method: http.MethodPost, path: "/api/v1/auth/register"},
		{method: http.MethodPost, path: "/api/v1/auth/forgot-password"},
		{method: http.MethodPost, path: "/api/v1/users/create"},
		{method: http.MethodGet, path: "/api/v1/users/events"},
		{method: http.MethodPost, path: "/api/v1/contacts/create"},
		{method: http.MethodGet, path: "/api/v1/contacts/get-all"},
		{method: http.MethodGet, path: "/api/v1/contacts/get-all/dt"},
		{method: http.MethodPost, path: "/api/v1/roles/create"},
		{method: http.MethodPost, path: "/api/v1/helicopters/create"},
		{method: http.MethodPost, path: "/api/v1/helicopter-usage/create"},
		{method: http.MethodGet, path: "/api/v1/helicopter-usage/get-all"},
		{method: http.MethodGet, path: "/api/v1/helicopter-usage/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/helicopter-usage/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/helicopter-usage/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/helicopter-usage/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/helicopters/:id/reports/next-number"},
		{method: http.MethodPost, path: "/api/v1/helicopter-files/create"},
		{method: http.MethodGet, path: "/api/v1/helicopter-files/events"},
		{method: http.MethodPost, path: "/api/v1/helicopter-files/upload"},
		{method: http.MethodPost, path: "/api/v1/helicopter-files/cancel-upload"},
		{method: http.MethodGet, path: "/api/v1/helicopter-files/get-all"},
		{method: http.MethodGet, path: "/api/v1/helicopter-files/get/:helicopter_id"},
		{method: http.MethodPatch, path: "/api/v1/helicopter-files/update"},
		{method: http.MethodDelete, path: "/api/v1/helicopter-files/delete"},
		{method: http.MethodGet, path: "/api/v1/flights/get-all"},
		{method: http.MethodGet, path: "/api/v1/flights/get"},
		{method: http.MethodGet, path: "/api/v1/fm-reports/get-all"},
		{method: http.MethodGet, path: "/api/v1/fm-reports/get/:flight_id"},
		{method: http.MethodPatch, path: "/api/v1/fm-reports/update/:flight_id"},
		{method: http.MethodPost, path: "/api/v1/fm-reports/complete/:flight_id"},
		{method: http.MethodPost, path: "/api/v1/flight-data/create"},
		{method: http.MethodGet, path: "/api/v1/flight-data/get/:uuid"},
		{method: http.MethodGet, path: "/api/v1/flight-data/get-all"},
		{method: http.MethodGet, path: "/api/v1/flight-data/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/flights-data/get-all"},
		{method: http.MethodGet, path: "/api/v1/flights-data/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/mission-type/get-all"},
		{method: http.MethodDelete, path: "/api/v1/mission/delete-by-id/:mission_id"},
		{method: http.MethodPost, path: "/api/v1/reserve-acs/create"},
		{method: http.MethodGet, path: "/api/v1/reserve-acs/get-all"},
		{method: http.MethodGet, path: "/api/v1/reserve-acs/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/reserve-acs/get/:id"},
		{method: http.MethodPatch, path: "/api/v1/reserve-acs/update"},
		{method: http.MethodDelete, path: "/api/v1/reserve-acs/delete"},
		{method: http.MethodGet, path: "/api/v1/after-flight-inspection/get"},
		{method: http.MethodPost, path: "/api/v1/after-flight-inspection/create"},
		{method: http.MethodPatch, path: "/api/v1/after-flight-inspection/update"},
		{method: http.MethodDelete, path: "/api/v1/after-flight-inspection/delete"},
		{method: http.MethodPost, path: "/api/v1/facilities/create"},
		{method: http.MethodPost, path: "/api/v1/bases/create"},
		{method: http.MethodGet, path: "/api/v1/bases/events"},
		{method: http.MethodPost, path: "/api/v1/medicine/create"},
		{method: http.MethodGet, path: "/api/v1/medicine/get-all"},
		{method: http.MethodGet, path: "/api/v1/medicine/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/medicine/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/medicine/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/medicine-group/create"},
		{method: http.MethodGet, path: "/api/v1/medicine-group/get-all"},
		{method: http.MethodGet, path: "/api/v1/medicine-group/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/medicine-group/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/medicine-group/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/motor-reaction/create"},
		{method: http.MethodGet, path: "/api/v1/motor-reaction/get-all"},
		{method: http.MethodGet, path: "/api/v1/motor-reaction/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/motor-reaction/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/motor-reaction/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/vocation/create"},
		{method: http.MethodGet, path: "/api/v1/vocation/get-all"},
		{method: http.MethodGet, path: "/api/v1/vocation/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/vocation/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/vocation/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/opc/create"},
		{method: http.MethodGet, path: "/api/v1/opc/get-all"},
		{method: http.MethodGet, path: "/api/v1/opc/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/opc/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/opc/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/forces-present/create"},
		{method: http.MethodGet, path: "/api/v1/forces-present/get-all"},
		{method: http.MethodGet, path: "/api/v1/forces-present/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/forces-present/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/forces-present/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/hospital/create"},
		{method: http.MethodGet, path: "/api/v1/hospital/get-all"},
		{method: http.MethodGet, path: "/api/v1/hospital/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/hospital/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/hospital/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/health-insurance-companies/create"},
		{method: http.MethodGet, path: "/api/v1/health-insurance-companies/get-all"},
		{method: http.MethodGet, path: "/api/v1/health-insurance-companies/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/health-insurance-companies/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/health-insurance-companies/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/federal-state/create"},
		{method: http.MethodGet, path: "/api/v1/federal-state/get-all"},
		{method: http.MethodGet, path: "/api/v1/federal-state/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/federal-state/update/:id"},
		{method: http.MethodDelete, path: "/api/v1/federal-state/delete/:id"},
		{method: http.MethodPost, path: "/api/v1/icao/create"},
		{method: http.MethodGet, path: "/api/v1/icao/get-all"},
		{method: http.MethodGet, path: "/api/v1/icao/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/icao/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/icao/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/land/create"},
		{method: http.MethodGet, path: "/api/v1/land/get-all"},
		{method: http.MethodGet, path: "/api/v1/land/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/land/update/:id"},
		{method: http.MethodDelete, path: "/api/v1/land/delete/:id"},
		{method: http.MethodPost, path: "/api/v1/master-settings/create"},
		{method: http.MethodGet, path: "/api/v1/master-settings/get"},
		{method: http.MethodPatch, path: "/api/v1/master-settings/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/master-settings/delete/:uuid"},
		{method: http.MethodGet, path: "/api/v1/branding/logo"},
		{method: http.MethodGet, path: "/api/v1/branding/login-cover"},
		{method: http.MethodGet, path: "/api/v1/branding/login-content"},
		{method: http.MethodGet, path: "/api/v1/file-manager/get-all"},
		{method: http.MethodGet, path: "/api/v1/file-manager/events"},
		{method: http.MethodGet, path: "/api/v1/file-manager/trash/get-all"},
		{method: http.MethodPatch, path: "/api/v1/file-manager/move"},
		{method: http.MethodDelete, path: "/api/v1/file-manager/delete"},
		{method: http.MethodPatch, path: "/api/v1/file-manager/restore"},
		{method: http.MethodDelete, path: "/api/v1/file-manager/purge-delete"},
		{method: http.MethodPost, path: "/api/v1/file-manager/folders/create"},
		{method: http.MethodGet, path: "/api/v1/file-manager/folders/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/file-manager/folders/update/:uuid"},
		{method: http.MethodPost, path: "/api/v1/file-manager/files/create"},
		{method: http.MethodPost, path: "/api/v1/file-manager/files/upload"},
		{method: http.MethodDelete, path: "/api/v1/file-manager/files/cancel-upload"},
		{method: http.MethodGet, path: "/api/v1/file-manager/files/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/file-manager/files/update/:uuid"},
		{method: http.MethodPost, path: "/api/v1/file-manager/attachments/create"},
		{method: http.MethodGet, path: "/api/v1/file-manager/attachments/get-all"},
		{method: http.MethodGet, path: "/api/v1/file-manager/attachments/get/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/file-manager/attachments/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/duty-roster/create"},
		{method: http.MethodGet, path: "/api/v1/duty-roster/get-all"},
		{method: http.MethodGet, path: "/api/v1/duty-roster/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/duty-roster/update"},
		{method: http.MethodDelete, path: "/api/v1/duty-roster/delete"},
		{method: http.MethodDelete, path: "/api/v1/duty-roster/crew"},
		{method: http.MethodPost, path: "/api/v1/air-rescuer-checklist/create"},
		{method: http.MethodGet, path: "/api/v1/air-rescuer-checklist/get-all"},
		{method: http.MethodGet, path: "/api/v1/air-rescuer-checklist/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/air-rescuer-checklist/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/air-rescuer-checklist/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/air-rescuer-checklist/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/air-rescuer-checklist/:uuid/items/create"},
		{method: http.MethodPatch, path: "/api/v1/air-rescuer-checklist/:uuid/items/reorder"},
		{method: http.MethodPatch, path: "/api/v1/air-rescuer-checklist/items/update/:item_uuid"},
		{method: http.MethodDelete, path: "/api/v1/air-rescuer-checklist/items/delete/:item_uuid"},
		{method: http.MethodPost, path: "/api/v1/insurance-patient-data/create"},
		{method: http.MethodGet, path: "/api/v1/insurance-patient-data/get/:uuid"},
		{method: http.MethodGet, path: "/api/v1/insurance-patient-data/get-all"},
		{method: http.MethodGet, path: "/api/v1/insurance-patient-data/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/insurance-patient-data/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/insurance-patient-data/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/patient-data/create"},
		{method: http.MethodGet, path: "/api/v1/patient-data/get/:uuid"},
		{method: http.MethodGet, path: "/api/v1/patient-data/get-all"},
		{method: http.MethodGet, path: "/api/v1/patient-data/get-all/dt"},
		{method: http.MethodPatch, path: "/api/v1/patient-data/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/patient-data/delete/:uuid"},
		{method: http.MethodGet, path: "/api/v1/dul/events"},
		{method: http.MethodPost, path: "/api/v1/hems-operational-data/create"},
		{method: http.MethodGet, path: "/api/v1/hems-operational-data/get-all"},
		{method: http.MethodGet, path: "/api/v1/hems-operational-data/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/hems-operational-data/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/hems-operational-data/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/hems-operational-data/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/hems-operation-category/create"},
		{method: http.MethodGet, path: "/api/v1/hems-operation-category/get-all"},
		{method: http.MethodGet, path: "/api/v1/hems-operation-category/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/hems-operation-category/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/hems-operation-category/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/hems-operation-category/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/hems-operation/create"},
		{method: http.MethodGet, path: "/api/v1/hems-operation/get-all"},
		{method: http.MethodGet, path: "/api/v1/hems-operation/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/hems-operation/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/hems-operation/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/hems-operation/delete/:uuid"},
		{method: http.MethodGet, path: "/swagger/*"},
	}

	for _, tc := range required {
		if !hasRoute(routes, tc.method, tc.path) {
			t.Fatalf("route %s %s not registered", tc.method, tc.path)
		}
	}

	legacy := []struct {
		method string
		path   string
	}{
		{method: http.MethodPost, path: "/api/v1/crews/create"},
		{method: http.MethodGet, path: "/api/v1/crews/get-all"},
		{method: http.MethodGet, path: "/api/v1/crews/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/crews/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/crews/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/crews/delete/:uuid"},
		{method: http.MethodPost, path: "/api/v1/hems-bases/create"},
		{method: http.MethodGet, path: "/api/v1/hems-bases/get-all"},
		{method: http.MethodGet, path: "/api/v1/hems-bases/get-all/dt"},
		{method: http.MethodGet, path: "/api/v1/hems-bases/get/:uuid"},
		{method: http.MethodPatch, path: "/api/v1/hems-bases/update/:uuid"},
		{method: http.MethodDelete, path: "/api/v1/hems-bases/delete/:uuid"},
	}
	for _, tc := range legacy {
		if hasRoute(routes, tc.method, tc.path) {
			t.Fatalf("legacy route %s %s should not be registered", tc.method, tc.path)
		}
	}
}

func hasRoute(routes []fiber.Route, method, path string) bool {
	for _, route := range routes {
		if route.Method == method && route.Path == path {
			return true
		}
	}
	return false
}
