package auth

import (
	"os"
	"path/filepath"
	"runtime"
	"slices"
	"strings"
	"testing"
)

func TestGatewaySourceDoesNotDependOnAuthenticationCoreVocabulary(t *testing.T) {
	_, currentFile, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatal("resolve current test file")
	}
	repositoryRoot := filepath.Clean(filepath.Join(filepath.Dir(currentFile), "..", "..", "..", ".."))
	appsRoot := filepath.Join(repositoryRoot, "apps")
	forbiddenMarkers := []string{
		strings.ToLower("key" + "cloak"),
		"/rea" + "lms/",
	}
	sourceExtensions := []string{".go", ".js", ".json", ".ts", ".tsx", ".yaml", ".yml"}
	skippedDirectories := []string{"coverage", "dist", "node_modules", "test-results"}
	var violations []string

	err := filepath.WalkDir(appsRoot, func(filePath string, entry os.DirEntry, walkErr error) error {
		if walkErr != nil {
			return walkErr
		}
		if entry.IsDir() {
			if filePath != appsRoot && slices.Contains(skippedDirectories, entry.Name()) {
				return filepath.SkipDir
			}
			return nil
		}
		if !slices.Contains(sourceExtensions, strings.ToLower(filepath.Ext(entry.Name()))) {
			return nil
		}
		content, readErr := os.ReadFile(filePath)
		if readErr != nil {
			return readErr
		}
		lowerContent := strings.ToLower(string(content))
		for _, marker := range forbiddenMarkers {
			if strings.Contains(lowerContent, marker) {
				relativePath, relativeErr := filepath.Rel(repositoryRoot, filePath)
				if relativeErr != nil {
					return relativeErr
				}
				violations = append(violations, filepath.ToSlash(relativePath))
				break
			}
		}
		return nil
	})
	if err != nil {
		t.Fatalf("scan Gateway sources: %v", err)
	}
	if len(violations) > 0 {
		t.Fatalf("Gateway source contains authentication-core-specific vocabulary: %s", strings.Join(violations, ", "))
	}
}
