package records

import (
	"encoding/json"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"testing"
)

type p1cDDecision struct {
	Status      string `json:"status"`
	Value       int64  `json:"value,omitempty"`
	Unit        string `json:"unit,omitempty"`
	Owner       string `json:"owner"`
	Meaning     string `json:"meaning"`
	Enforcement string `json:"enforcement"`
	Gate        string `json:"gate,omitempty"`
}

type p1cDContractDecisionReport struct {
	Schema         string `json:"schema"`
	Classification string `json:"classification"`
	Revisions      struct {
		EnvelopeNexusCRM  string `json:"envelope_nexuscrm"`
		RouteNexusCRM     string `json:"route_nexuscrm"`
		ExecutionNexusCRM string `json:"execution_nexuscrm"`
		AppPacks          string `json:"app_packs"`
		Fixture           string `json:"issue_tracker_fixture"`
	} `json:"revisions"`
	Decisions struct {
		SelectedFields         p1cDDecision `json:"selected_fields"`
		SemanticRequestBytes   p1cDDecision `json:"semantic_request_bytes"`
		CompleteResponseBytes  p1cDDecision `json:"complete_response_bytes"`
		ObjectIdentifierBytes  p1cDDecision `json:"object_identifier_bytes"`
		FieldIdentifierBytes   p1cDDecision `json:"field_identifier_bytes"`
		RecordIdentifierBytes  p1cDDecision `json:"record_identifier_bytes"`
		ExplicitDeadline       p1cDDecision `json:"explicit_deadline"`
		RuntimeAttemptCap      p1cDDecision `json:"runtime_attempt_cap"`
		L1RouteBudget          p1cDDecision `json:"l1_route_budget"`
		L1AutomaticRetries     p1cDDecision `json:"l1_automatic_retries"`
		FailFastAdmission      p1cDDecision `json:"fail_fast_admission"`
		ReplicaConcurrency     p1cDDecision `json:"replica_concurrency"`
		TransportReceiveBytes  p1cDDecision `json:"transport_receive_bytes"`
		TransportSendBytes     p1cDDecision `json:"transport_send_bytes"`
		TransportCompressionV1 p1cDDecision `json:"transport_compression_v1"`
	} `json:"decisions"`
	ProductionCutoverGates []string `json:"production_cutover_gates"`
}

func TestP1cDContractDecisionGolden(t *testing.T) {
	report := p1cDBuildContractDecisionReport(t)
	_, file, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatal("resolve P1c-D decision test path")
	}
	goldenPath := strings.TrimSuffix(file, "selected_root_contract_decision_test.go") + "testdata/selected_root_contract_decision_golden.json"
	wantBytes, err := os.ReadFile(goldenPath)
	if err != nil {
		t.Fatalf("read P1c-D golden: %v", err)
	}
	var want p1cDContractDecisionReport
	if err := json.Unmarshal(wantBytes, &want); err != nil {
		t.Fatalf("decode P1c-D golden: %v", err)
	}
	if !reflect.DeepEqual(report, want) {
		got, _ := json.MarshalIndent(report, "", "  ")
		t.Fatalf("P1c-D contract decision changed; review and update the ADR and golden deliberately:\n%s", got)
	}
}

func p1cDBuildContractDecisionReport(t *testing.T) p1cDContractDecisionReport {
	t.Helper()
	envelope := p1cM2eBuildValidEnvelopeReport(t)
	route := p1cM2cSBuildRouteBudgetReport(t)
	_, file, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatal("resolve P1c-D revision path")
	}
	pins := p1cM2eRevisionPins(t, filepath.Join(filepath.Dir(file), "..", "tests", "performance", "selected-root-read", "revisions.env"))
	executionRevision := pins["P1C_M2DC_NEXUSCRM_EVIDENCE_REVISION"]
	if executionRevision == "" {
		t.Fatal("P1c-D decision lost its M2d-C execution evidence revision")
	}

	approved := func(value int64, unit, owner, meaning, enforcement string) p1cDDecision {
		return p1cDDecision{Status: "APPROVED", Value: value, Unit: unit, Owner: owner, Meaning: meaning, Enforcement: enforcement}
	}
	deferred := func(value int64, unit, owner, meaning, enforcement, gate string) p1cDDecision {
		return p1cDDecision{Status: "DEFERRED", Value: value, Unit: unit, Owner: owner, Meaning: meaning, Enforcement: enforcement, Gate: gate}
	}

	var report p1cDContractDecisionReport
	report.Schema = "p1c-d.v1"
	report.Classification = "approved selected-root semantic contract; deployment and wire values remain deferred to their owning phases"
	report.Revisions.EnvelopeNexusCRM = envelope.Revisions.NexusCRMBase
	report.Revisions.RouteNexusCRM = route.Revisions.NexusCRMBase
	report.Revisions.ExecutionNexusCRM = executionRevision
	report.Revisions.AppPacks = envelope.Revisions.AppPacks
	report.Revisions.Fixture = envelope.Revisions.Fixture
	report.Decisions.SelectedFields = approved(int64(envelope.Candidate.SelectedFields), "submitted entries and canonical unique fields", "Runtime capability", "duplicates are allowed but neither the submitted list nor the deduplicated selection may exceed the maximum", "P2 wire/server validation before metadata or repository access")
	report.Decisions.SemanticRequestBytes = approved(int64(envelope.Candidate.SemanticRequestBytes), "bytes", "Runtime capability", "defensive semantic outer cap; it is not the largest structurally valid v1 request and is not a wire-size claim", "P2 canonical semantic-size and exact/one-over validation")
	report.Decisions.CompleteResponseBytes = approved(int64(envelope.Candidate.CompleteResponseBytes), "bytes", "Runtime capability", "complete authorized projection including required receipts; overflow returns no partial result", "P2 canonical semantic-size and exact/one-over validation")
	report.Decisions.ObjectIdentifierBytes = approved(int64(envelope.Candidate.ObjectIdentifierBytes), "ASCII bytes", "metadata naming contract", "logical name maps directly to the TiDB physical identifier", "P2 request validation before metadata or repository access")
	report.Decisions.FieldIdentifierBytes = approved(int64(envelope.Candidate.FieldIdentifierBytes), "ASCII bytes", "metadata naming contract", "logical name maps directly to the TiDB physical identifier", "P2 request validation before metadata or repository access")
	report.Decisions.RecordIdentifierBytes = approved(int64(envelope.Candidate.RecordIdentifierBytes), "UTF-8 bytes", "Runtime read-input contract", "opaque resource bound only; object schemas retain their authoritative stored-ID widths", "P2 request validation before metadata or repository access")
	report.Decisions.ExplicitDeadline = approved(1, "required boolean", "Runtime capability", "every attempt carries a trusted deadline; a missing deadline is INVALID_REQUEST", "P2 semantic vectors and P3 server enforcement")
	report.Decisions.RuntimeAttemptCap = approved(route.Candidate.RuntimeAttemptCapNanoseconds, "nanoseconds", "Runtime capability", "maximum execution budget per attempt, not a latency SLO or success guarantee; a shorter trusted deadline wins", "P3 server enforcement and cancellation tests")
	report.Decisions.L1RouteBudget = deferred(route.Candidate.RouteBudgetNanoseconds, "nanoseconds", "sfcrm L1 route owner", "candidate end-to-end route policy, not an App-blind Runtime SLO", "P4/P5 real route", "approve from representative route latency and close the retained 512-field/c16 tail before production cutover")
	report.Decisions.L1AutomaticRetries = deferred(int64(route.Candidate.MaxRetries), "retries", "sfcrm L1 route owner", "candidate retry count; only UNAVAILABLE and eligible STALE_STATE are semantically retryable within the original parent deadline", "P4/P5 real route", "prove no retry amplification and close route-budget arithmetic against real Gateway/AppService overhead")
	report.Decisions.FailFastAdmission = approved(1, "required boolean", "Runtime capability", "bounded admission rejects excess work with RESOURCE_EXHAUSTED instead of creating an unbounded queue", "P3 replica admission and load-shedding tests")
	report.Decisions.ReplicaConcurrency = deferred(16, "in-flight reads per replica", "Runtime deployment", "candidate starting configuration, not a protocol or semantic constant", "P3 deployment configuration", "measure real split-process replicas and prove bounded queue, pool, memory, and retry behavior")
	report.Decisions.TransportReceiveBytes = deferred(128*1024, "bytes", "P2 wire transport", "candidate receive cap with reserved room above the semantic request cap", "P2 generated codec and transport configuration", "exact/one-over codec replay must prove framing headroom")
	report.Decisions.TransportSendBytes = deferred(2*1024*1024, "bytes", "P2 wire transport", "candidate send cap with reserved room above the complete semantic response cap", "P2 generated codec and transport configuration", "exact/one-over codec replay must prove framing headroom")
	report.Decisions.TransportCompressionV1 = approved(0, "enabled boolean", "runtime.records.read-selected-root.v1", "compression is disabled for v1; a later change requires an explicit capability decision and decompression limits", "P2 client/server transport configuration and oversized-message tests")
	report.ProductionCutoverGates = []string{
		"P2: replay semantic exact/one-over vectors through the generated codec and prove receive/send caps and compression-disabled behavior",
		"P3: prove real replica fail-fast admission, cancellation, unavailable-process behavior, and choose deployment concurrency",
		"P4/P5: representative sfcrm route run must disposition the retained two-of-5000 512-field/c16 two-second deadline outcomes before traffic cutover",
	}
	return report
}

func TestP1cDApprovedAndDeferredOwnership(t *testing.T) {
	report := p1cDBuildContractDecisionReport(t)
	approved := []p1cDDecision{
		report.Decisions.SelectedFields,
		report.Decisions.SemanticRequestBytes,
		report.Decisions.CompleteResponseBytes,
		report.Decisions.ObjectIdentifierBytes,
		report.Decisions.FieldIdentifierBytes,
		report.Decisions.RecordIdentifierBytes,
		report.Decisions.ExplicitDeadline,
		report.Decisions.RuntimeAttemptCap,
		report.Decisions.FailFastAdmission,
		report.Decisions.TransportCompressionV1,
	}
	for _, decision := range approved {
		if decision.Status != "APPROVED" || decision.Enforcement == "" {
			t.Fatalf("approved decision lacks status or enforcement owner: %#v", decision)
		}
	}
	deferred := []p1cDDecision{
		report.Decisions.L1RouteBudget,
		report.Decisions.L1AutomaticRetries,
		report.Decisions.ReplicaConcurrency,
		report.Decisions.TransportReceiveBytes,
		report.Decisions.TransportSendBytes,
	}
	for _, decision := range deferred {
		if decision.Status != "DEFERRED" || decision.Owner == "" || decision.Gate == "" {
			t.Fatalf("deferred decision lacks owner or finite gate: %#v", decision)
		}
	}
	if report.Decisions.L1RouteBudget.Owner == report.Decisions.RuntimeAttemptCap.Owner {
		t.Fatal("L1 route SLO and Runtime attempt cap must not have the same owner")
	}
	if len(report.ProductionCutoverGates) != 3 {
		t.Fatalf("production cutover gates = %d, want 3 finite owner-aligned gates", len(report.ProductionCutoverGates))
	}
}

func TestP1cDRevisionPinsRemainComplete(t *testing.T) {
	_, file, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatal("resolve P1c-D revision path")
	}
	pins := p1cM2eRevisionPins(t, filepath.Join(filepath.Dir(file), "..", "tests", "performance", "selected-root-read", "revisions.env"))
	if pins["P1C_M1_APP_PACKS_REVISION"] == "" || pins["P1C_M1_FIXTURE_REVISION"] == "" || pins["P1C_M2DC_NEXUSCRM_EVIDENCE_REVISION"] == "" {
		t.Fatal("P1c-D decision lost its app-packs, fixture, or execution evidence revision")
	}
}
