package serverruntime

import (
	"go/ast"
	"go/parser"
	gotoken "go/token"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"testing"
)

func TestUIAPIReframeDoesNotRegressToEngineOwnedWireDTOs(t *testing.T) {
	for _, rel := range []string{
		filepath.Join("backend", "internal", "features", "uiapi"),
		filepath.Join("backend", "internal", "domain", "ports", "uiapi.go"),
	} {
		path := repoPath(rel)
		if _, err := os.Stat(path); err == nil {
			t.Fatalf("%s must not exist; #2708 keeps Salesforce UI API wire ownership out of L0 engines/ports", filepath.ToSlash(rel))
		} else if !os.IsNotExist(err) {
			t.Fatalf("stat %s: %v", filepath.ToSlash(rel), err)
		}
	}

	for _, path := range uiAPIReframeL0ProductionFiles(t) {
		rel := filepath.ToSlash(mustRel(t, repoPath(), path))
		if uiAPIReframeAllowedTransitionalWireOwner(rel) {
			continue
		}
		data, err := os.ReadFile(path)
		if err != nil {
			t.Fatalf("read %s: %v", path, err)
		}
		if matches := uiAPIReframeForbiddenWireMatches(t, rel, data); len(matches) > 0 {
			t.Fatalf("%s contains Salesforce UI API/describe wire grammar below the REST/dialect boundary: %v", rel, matches)
		}
	}
}

func TestUIAPIReframeGuardMatchesDefaultRuntimeWireGrammar(t *testing.T) {
	source := []byte("package planted\n\n" +
		"const recordUIPath = \"/ui-api/record-ui\"\n" +
		"const objectInfoPath = \"/ui-api/object-info\"\n" +
		"const describePath = \"/services/data/v63.0/sobjects/Account/describe\"\n" +
		"type payload struct {\n" +
		"  ObjectInfos map[string]any `json:\"objectInfos\"`\n" +
		"  LayoutTypes []string `json:\"layoutTypes\"`\n" +
		"  Records []any `json:\"records\"`\n" +
		"  Fields []any `json:\"fields\"`\n" +
		"  DisplayValue string `json:\"displayValue\"`\n" +
		"}\n")

	matches := uiAPIReframeForbiddenWireMatches(t, "backend/pkg/serverruntime/planted.go", source)
	for _, want := range []string{
		"/ui-api",
		"record-ui",
		"object-info",
		"/services/data",
		"objectInfos",
		"layoutTypes",
		"records",
		"fields",
		"displayValue",
	} {
		if !wireMatchContains(matches, want) {
			t.Fatalf("planted UI API / describe wire grammar %q was not detected; matches=%v", want, matches)
		}
	}
}

func TestUIAPIReframeGuardScansDefaultServerDependencyClosure(t *testing.T) {
	scanned := map[string]bool{}
	for _, path := range uiAPIReframeL0ProductionFiles(t) {
		scanned[filepath.ToSlash(mustRel(t, repoPath(), path))] = true
	}
	for _, rel := range []string{
		"nexuscrm-kernel/pkg/oauthroutes/patterns.go",
	} {
		if !scanned[rel] {
			t.Fatalf("%s is in the default server dependency closure but was not scanned for UI API / describe wire grammar", rel)
		}
	}
}

func TestUIAPIReframeGuardMatchesServiceDataRouteGrammarWithoutDescribe(t *testing.T) {
	source := []byte("package planted\n\n" +
		"const standardActionPath = \"/services/data/v63.0/actions/standard/convertLead\"\n")

	matches := uiAPIReframeForbiddenWireMatches(t, "backend/pkg/serverruntime/planted.go", source)
	if !wireMatchContains(matches, "/services/data") {
		t.Fatalf("planted Salesforce route grammar /services/data was not detected; matches=%v", matches)
	}
}

func TestUIAPIReframeGuardAllowsGenericFieldPayloads(t *testing.T) {
	source := []byte("package generic\n\n" +
		"type payload struct {\n" +
		"  Fields []string `json:\"fields\"`\n" +
		"  Records []string `json:\"records\"`\n" +
		"}\n")

	if matches := uiAPIReframeForbiddenWireMatches(t, "backend/internal/controlplane/packs/generic.go", source); len(matches) != 0 {
		t.Fatalf("generic field/record payload was classified as UI API wire grammar: %v", matches)
	}
}

func TestUIAPIReframeGuardRejectsLegacyRESTDescribeOwners(t *testing.T) {
	for _, rel := range []string{
		"backend/internal/interfaces/rest/sobject_describe.go",
		"backend/internal/interfaces/rest/salesforce_dtos.go",
	} {
		if uiAPIReframeAllowedTransitionalWireOwner(rel) {
			t.Fatalf("%s should no longer be accepted as a transitional Salesforce describe owner", rel)
		}
	}

	for _, rel := range []string{
		"nexuscrm-api-host/dialecttransport/binder.go",
		"backend/distributions/crm/product.go",
	} {
		if !uiAPIReframeAllowedTransitionalWireOwner(rel) {
			t.Fatalf("%s should remain an explicit dialect/distribution wire owner", rel)
		}
	}
}

func uiAPIReframeL0ProductionFiles(t *testing.T) []string {
	t.Helper()
	repoRoot, err := filepath.Abs(repoPath())
	if err != nil {
		t.Fatalf("abs repo root: %v", err)
	}
	backendRoot := repoPath("backend")
	cmd := exec.Command("go", "list", "-deps", "-f", "{{if not .Standard}}{{.Dir}}{{end}}", "./cmd/runtime-api")
	cmd.Dir = backendRoot
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("go list default server deps: %v\n%s", err, out)
	}

	seenDirs := map[string]struct{}{}
	seenFiles := map[string]struct{}{}
	var files []string
	for _, line := range strings.Split(string(out), "\n") {
		dir := strings.TrimSpace(line)
		if dir == "" {
			continue
		}
		dirAbs, err := filepath.Abs(dir)
		if err != nil {
			t.Fatalf("abs go list dir %s: %v", dir, err)
		}
		relDir, ok := uiAPIReframeRelUnderRoot(repoRoot, dirAbs)
		if !ok {
			continue
		}
		if _, ok := seenDirs[relDir]; ok {
			continue
		}
		seenDirs[relDir] = struct{}{}
		for _, path := range productionGoFiles(t, repoPath(relDir)) {
			if fileHasBuildTag(t, path, "crm") {
				continue
			}
			relFile := filepath.ToSlash(mustRel(t, repoPath(), path))
			if _, ok := seenFiles[relFile]; ok {
				continue
			}
			seenFiles[relFile] = struct{}{}
			files = append(files, path)
		}
	}
	sort.Strings(files)
	return files
}

func uiAPIReframeRelUnderRoot(root, target string) (string, bool) {
	rel, err := filepath.Rel(root, target)
	if err != nil || rel == "." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) || rel == ".." {
		return "", false
	}
	return rel, true
}

func uiAPIReframeAllowedTransitionalWireOwner(rel string) bool {
	rel = filepath.ToSlash(rel)
	for _, prefix := range []string{
		"backend/internal/interfaces/dialect/",
		"backend/distributions/",
		"nexuscrm-api-host/dialecttransport/",
	} {
		if strings.HasPrefix(rel, prefix) {
			return true
		}
	}
	return false
}

func uiAPIReframeForbiddenWireMatches(t *testing.T, rel string, source []byte) []string {
	t.Helper()
	literals := goStringLiterals(t, rel, source)
	hasUIAPIContext := false
	for _, literal := range literals {
		if uiAPIReframeLiteralHasStrongWireGrammar(literal) {
			hasUIAPIContext = true
			break
		}
	}

	var matches []string
	seen := map[string]struct{}{}
	addMatch := func(token, literal string) {
		if uiAPIReframeAllowedWireMatch(rel, token, literal) {
			return
		}
		if _, ok := seen[token]; ok {
			return
		}
		seen[token] = struct{}{}
		matches = append(matches, token)
	}

	for _, literal := range literals {
		for _, token := range []string{
			"/ui-api",
			"record-ui",
			"object-info",
			"record-defaults",
			"objectInfos",
			"recordTypeInfos",
			"layoutTypes",
			"childRelationships",
			"displayValue",
		} {
			if strings.Contains(literal, token) {
				addMatch(token, literal)
			}
		}
		if strings.Contains(literal, "/services/data") {
			addMatch("/services/data", literal)
		}
		if hasUIAPIContext {
			for _, token := range []string{"records", "fields"} {
				if uiAPIReframeLiteralHasJSONKey(literal, token) {
					addMatch(token, literal)
				}
			}
		}
	}
	return matches
}

func goStringLiterals(t *testing.T, rel string, source []byte) []string {
	t.Helper()
	file, err := parser.ParseFile(gotoken.NewFileSet(), rel, source, 0)
	if err != nil {
		t.Fatalf("parse %s: %v", rel, err)
	}
	var literals []string
	ast.Inspect(file, func(n ast.Node) bool {
		lit, ok := n.(*ast.BasicLit)
		if !ok || lit.Kind != gotoken.STRING {
			return true
		}
		value, err := strconv.Unquote(lit.Value)
		if err != nil {
			t.Fatalf("unquote string literal in %s: %v", rel, err)
		}
		literals = append(literals, value)
		return true
	})
	return literals
}

func uiAPIReframeLiteralHasStrongWireGrammar(literal string) bool {
	for _, token := range []string{
		"/ui-api",
		"record-ui",
		"object-info",
		"record-defaults",
		"objectInfos",
		"recordTypeInfos",
		"layoutTypes",
		"childRelationships",
		"displayValue",
	} {
		if strings.Contains(literal, token) {
			return true
		}
	}
	return strings.Contains(literal, "/services/data")
}

func uiAPIReframeLiteralHasJSONKey(literal, key string) bool {
	return literal == key ||
		strings.Contains(literal, `json:"`+key+`"`) ||
		strings.Contains(literal, `json:"`+key+`,`)
}

func uiAPIReframeAllowedWireMatch(rel, token, literal string) bool {
	rel = filepath.ToSlash(rel)
	if token != "/services/data" {
		return false
	}
	switch rel {
	case "nexuscrm-kernel/pkg/oauthroutes/patterns.go":
		return strings.Contains(literal, "/services/data")
	default:
		return false
	}
}

func wireMatchContains(matches []string, want string) bool {
	for _, got := range matches {
		if got == want {
			return true
		}
	}
	return false
}
