package rest

import (
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"testing"
)

func TestGlobalErrorHandlerIngressStaysCentralized(t *testing.T) {
	_, currentFile, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatal("runtime.Caller failed")
	}
	interfacesDir := filepath.Clean(filepath.Join(filepath.Dir(currentFile), ".."))
	repoRoot := filepath.Clean(filepath.Join(interfacesDir, "../../.."))

	directContextErrorCounts := map[string]int{}
	var directContextErrorSites []string
	err := filepath.WalkDir(interfacesDir, func(path string, entry os.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if entry.IsDir() {
			return nil
		}
		name := entry.Name()
		if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
			return nil
		}
		content, err := os.ReadFile(path)
		if err != nil {
			return err
		}
		rel, err := filepath.Rel(repoRoot, path)
		if err != nil {
			rel = path
		}
		for i, line := range strings.Split(string(content), "\n") {
			if contextErrorCall.FindString(line) != "" {
				directContextErrorCounts[rel]++
				directContextErrorSites = append(directContextErrorSites, rel+":"+strconv.Itoa(i+1))
			}
		}
		return nil
	})
	if err != nil {
		t.Fatalf("walk %s: %v", interfacesDir, err)
	}

	wantCounts := map[string]int{"backend/internal/interfaces/rest/helpers.go": 1}
	if !sameCounts(directContextErrorCounts, wantCounts) {
		t.Fatalf("direct gin.Context.Error sites changed\n got:\n%s\nwant exactly one call in backend/internal/interfaces/rest/helpers.go\n\nKeep GlobalErrorHandler ingress centralized through rest.RespondAppError; dialect route groups install the DomainWireError projector at mount time.",
			strings.Join(directContextErrorSites, "\n"),
		)
	}
}

var contextErrorCall = regexp.MustCompile(`\bc\.Error\(`)

func sameCounts(a, b map[string]int) bool {
	if len(a) != len(b) {
		return false
	}
	for key, av := range a {
		if b[key] != av {
			return false
		}
	}
	return true
}
