package httproutes

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestActivityTemplateRuntimeRoutesAreProfileProtectedAndPreservePathValues(t *testing.T) {
	profileCalls := 0
	profileWrap := func(next http.HandlerFunc) http.Handler {
		return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
			profileCalls++
			next(writer, request)
		})
	}
	identityWrap := func(next http.HandlerFunc) http.Handler { return next }
	marker := func(name string) http.HandlerFunc {
		return func(writer http.ResponseWriter, request *http.Request) {
			writer.Header().Set("X-Handler", name)
			writer.Header().Set("X-Template-Code", request.PathValue("template_code"))
			writer.Header().Set("X-Task-Key", request.PathValue("task_key"))
			writer.WriteHeader(http.StatusNoContent)
		}
	}
	mux := http.NewServeMux()
	routeSet := routes{mux: mux, config: Config{
		PublicWrap: identityWrap, AuthWrap: identityWrap, ProfileWrap: profileWrap,
		Task: TaskHandlers{
			GetCurrentActivityTemplate:           marker("current"),
			VisitActivityTemplate:                marker("visit"),
			ListActivityTemplateTasks:            marker("tasks"),
			ClaimActivityTemplateTask:            marker("claim"),
			ListActivityTemplateDailyLeaderboard: marker("daily"),
			ListActivityTemplateTotalLeaderboard: marker("total"),
		},
	}}
	routeSet.registerTaskRoutes()

	tests := []struct {
		method       string
		path         string
		handler      string
		templateCode string
		taskKey      string
	}{
		{http.MethodGet, "/api/v1/activities/templates/current", "current", "", ""},
		{http.MethodPost, "/api/v1/activities/templates/summer/visit", "visit", "summer", ""},
		{http.MethodGet, "/api/v1/activities/templates/summer/tasks", "tasks", "summer", ""},
		{http.MethodPost, "/api/v1/activities/templates/summer/tasks/gift-10/claim", "claim", "summer", "gift-10"},
		{http.MethodGet, "/api/v1/activities/templates/summer/leaderboards/daily", "daily", "summer", ""},
		{http.MethodGet, "/api/v1/activities/templates/summer/leaderboards/total", "total", "summer", ""},
	}
	for _, test := range tests {
		t.Run(test.handler, func(t *testing.T) {
			recorder := httptest.NewRecorder()
			mux.ServeHTTP(recorder, httptest.NewRequest(test.method, test.path, nil))
			if recorder.Code != http.StatusNoContent || recorder.Header().Get("X-Handler") != test.handler {
				t.Fatalf("route mismatch: code=%d handler=%q body=%s", recorder.Code, recorder.Header().Get("X-Handler"), recorder.Body.String())
			}
			if recorder.Header().Get("X-Template-Code") != test.templateCode || recorder.Header().Get("X-Task-Key") != test.taskKey {
				t.Fatalf("path values mismatch: template=%q task=%q", recorder.Header().Get("X-Template-Code"), recorder.Header().Get("X-Task-Key"))
			}
		})
	}
	if profileCalls != len(tests) {
		t.Fatalf("all activity template routes must use profile middleware: got=%d want=%d", profileCalls, len(tests))
	}
}
