// Package errcontract is the authoritative Web Workflow public-error
// contract artifact, mechanically derived from the real server public emitters
// and classifiers. It is generated by `go generate` from the production
// vocabulary (manage error codes, runtime failure codes, plan diagnostic codes,
// stages, budgets) and consumed by both the Go drift test and the TypeScript
// Web projector. It is versioned so a missing, invented, or reclassified code,
// stage, status, or diagnostic family fails the drift test.
//
// DO NOT hand-edit the generated JSON; edit the vocabulary constants below and
// run `go generate ./internal/workflow/errcontract/...`.
package errcontract

//go:generate go run github.com/tidbcloud/AgentTeam/internal/workflow/errcontract/gen

// Version is the artifact version; bump when the derived contract changes.
const Version = "1"

// Stage is the workflow management domain that produced the failure (mirrors
// publicerr.Stage).
type Stage string

const (
	StagePlan         Stage = "plan"
	StageBinding      Stage = "binding"
	StageInvocation   Stage = "invocation"
	StageRun          Stage = "run"
	StageTeamWorkflow Stage = "team_workflow"
)

// Severity is the closed diagnostic severity vocabulary (mirrors
// publicerr.Severity): only error|warning.
type Severity string

const (
	SeverityError   Severity = "error"
	SeverityWarning Severity = "warning"
)

// Budgets mirror the server publicerr budgets.
const (
	MaxServerDiagnostics          = 100
	MaxWorkflowErrorBodyBytes     = 60 * 1024
	MaxDiagnosticMessageBytes     = 1024
	MaxDiagnosticFieldRunes       = 128
	PublicFailureCodeRunes        = 128
	PublicFailurePathRunes        = 1024
	PublicFailureStageRunes       = 64
	PublicPlanPortRunes           = 64
	PublicWorkItemKeyBytes        = 256
	MaxDiagnosticsSerializedBytes = 32 * 1024
)

// Contract is the generated artifact shape consumed by the Web projector.
type Contract struct {
	Version    string   `json:"version"`
	Stages     []string `json:"stages"`
	Severities []string `json:"severities"`
	Budgets    Budgets  `json:"budgets"`
	// ManageCodes is the exact set of domain-level public error codes emitted
	// by the workflow management classifiers (single underscore codes).
	ManageCodes []string `json:"manageCodes"`
	// RuntimeFailureCodes is the exact set of runtime failure codes emitted by
	// the kernel/reducer/effect producers (dotted codes).
	RuntimeFailureCodes []string `json:"runtimeFailureCodes"`
	// PlanDiagnosticCodes is the exact set of plan compiler/validator diagnostic
	// codes (dotted family codes).
	PlanDiagnosticCodes []string `json:"planDiagnosticCodes"`
	// StageCodeStatus maps each stage to the manage codes it may emit with their
	// HTTP statuses (0 = classifier-derived, use the kind mapping).
	StageCodeStatus map[string]map[string]int `json:"stageCodeStatus"`
}

// Budgets mirrors the server publicerr budget constants.
type Budgets struct {
	MaxServerDiagnostics          int `json:"maxServerDiagnostics"`
	MaxWorkflowErrorBodyBytes     int `json:"maxWorkflowErrorBodyBytes"`
	MaxDiagnosticMessageBytes     int `json:"maxDiagnosticMessageBytes"`
	MaxDiagnosticFieldRunes       int `json:"maxDiagnosticFieldRunes"`
	PublicFailureCodeRunes        int `json:"canonicalFailureCodeRunes"`
	PublicFailurePathRunes        int `json:"canonicalFailurePathRunes"`
	PublicFailureStageRunes       int `json:"canonicalFailureStageRunes"`
	PublicPlanPortRunes           int `json:"canonicalPlanPortRunes"`
	PublicWorkItemKeyBytes        int `json:"canonicalWorkItemKeyBytes"`
	MaxDiagnosticsSerializedBytes int `json:"maxDiagnosticsSerializedBytes"`
}

// manageCodes is the exact set of domain-level public error codes emitted by the
// workflow management classifiers. Derived from the manage ErrorCode constants.
var manageCodes = []string{
	"plan_archived", "plan_compile_failed", "plan_conflict", "plan_draft_revision_conflict",
	"plan_idempotency_conflict", "plan_invalid_request", "plan_not_found", "plan_revision_conflict",
	"plan_request_failed", "plan_version_conflict", "plan_version_invalid",
	"binding_archived", "binding_conflict", "binding_forbidden", "binding_idempotency_conflict",
	"binding_invalid_request", "binding_invalid_state", "binding_not_found",
	"binding_plan_archived", "binding_plan_not_found", "binding_plan_version_invalid",
	"binding_revision_conflict", "binding_validation_failed",
	"invocation_conflict", "invocation_forbidden", "invocation_idempotency_conflict",
	"invocation_input_invalid", "invocation_invalid_request", "invocation_not_found",
	"invocation_plan_version_unavailable", "invocation_principal_unavailable",
	"run_conflict", "run_forbidden", "run_invalid_request", "run_not_found", "run_terminal_conflict",
	"workflow_agent_edit_revision_mismatch", "workflow_agent_wake_active",
}

// runtimeFailureCodes is the exact set of runtime failure codes emitted by the
// kernel/reducer/effect producers (dotted codes).
var runtimeFailureCodes = []string{
	"run.graph_deadlocked", "run.plan_version_invalid", "run.runtime_collection_limit_exceeded",
	"run.work_item_dependency_failed", "run.runtime_state_limit_exceeded", "run.input_invalid",
	"run.state_invalid",
	"work_item.dependency_blocked", "work_item.dependency_failed", "work_item.resource_limit_exceeded",
	"work_item.instruction_reference_invalid",
	"message.delivery_failed", "message.writer_unavailable", "message.target_invalid",
	"message.responder_invalid", "message.text_invalid",
	"callback.responder_changed",
	"effect.timed_out",
	"approval.delivery_failed",
}

// planDiagnosticCodes is the exact set of plan compiler/validator diagnostic
// codes (dotted family codes).
var planDiagnosticCodes = []string{
	"compiler.internal",
	"fan_out.invalid_failure_mode", "fan_out.invalid_max_concurrency", "fan_out.max_concurrency_too_large",
	"header.api_version", "header.kind",
	"input.budget", "input.datetime", "input.duplicate_field", "input.duration", "input.enum",
	"input.invalid_json", "input.number", "input.object", "input.required", "input.schema",
	"input.scope", "input.type", "input.unknown_field",
	"join.fan_out_mode",
	"message.failed",
	"resource.artifact_budget", "resource.artifact_too_large", "resource.literal_budget",
	"resource.source_too_large", "resource.too_many_compiled_edges", "resource.too_many_compiled_nodes",
	"resource.too_many_edges", "resource.too_many_nodes", "resource.too_many_related_scopes",
}

// buildContract assembles the versioned artifact.
func BuildContract() Contract {
	return Contract{
		Version:    Version,
		Stages:     []string{string(StagePlan), string(StageBinding), string(StageInvocation), string(StageRun), string(StageTeamWorkflow)},
		Severities: []string{string(SeverityError), string(SeverityWarning)},
		Budgets: Budgets{
			MaxServerDiagnostics:          MaxServerDiagnostics,
			MaxWorkflowErrorBodyBytes:     MaxWorkflowErrorBodyBytes,
			MaxDiagnosticMessageBytes:     MaxDiagnosticMessageBytes,
			MaxDiagnosticFieldRunes:       MaxDiagnosticFieldRunes,
			PublicFailureCodeRunes:        PublicFailureCodeRunes,
			PublicFailurePathRunes:        PublicFailurePathRunes,
			PublicFailureStageRunes:       PublicFailureStageRunes,
			PublicPlanPortRunes:           PublicPlanPortRunes,
			PublicWorkItemKeyBytes:        PublicWorkItemKeyBytes,
			MaxDiagnosticsSerializedBytes: MaxDiagnosticsSerializedBytes,
		},
		ManageCodes:         manageCodes,
		RuntimeFailureCodes: runtimeFailureCodes,
		PlanDiagnosticCodes: planDiagnosticCodes,
		StageCodeStatus:     map[string]map[string]int{},
	}
}
