// Package evidence defines the platform-owned release, UAT, security, and
// guard evidence contract. It intentionally uses platform types rather than
// re-exporting legacy service package shapes.
package evidence

import "time"

type Result string

const (
	ResultPass          Result = "pass"
	ResultFail          Result = "fail"
	ResultPartial       Result = "partial"
	ResultBlocked       Result = "blocked"
	ResultMissing       Result = "missing"
	ResultNotApplicable Result = "not_applicable"
)

// InvariantID identifies a named product or platform invariant that evidence
// can prove. These constants are the canonical catalog — extend here before
// using a new ID in any evidence item or UAT producer.
type InvariantID = string

// Product flow invariants (GPUaaS).
const (
	InvariantGPUaaSLaunch   InvariantID = "GPUAAS-LAUNCH-001"
	InvariantGPUaaSConnect  InvariantID = "GPUAAS-CONNECT-001"
	InvariantGPUaaSRelease  InvariantID = "GPUAAS-RELEASE-001"
	InvariantGPUaaSCapacity InvariantID = "GPUAAS-CAPACITY-001"
)

// Product flow invariants (App Platform).
const (
	InvariantAppContract InvariantID = "APP-CONTRACT-001"
	InvariantAppLaunch   InvariantID = "APP-LAUNCH-001"
	InvariantAppFailure  InvariantID = "APP-FAILURE-001"
)

// Platform shared-service invariants.
const (
	InvariantPlatformAudit        InvariantID = "PLATFORM-AUDIT-001"
	InvariantPlatformOutbox       InvariantID = "PLATFORM-OUTBOX-001"
	InvariantPlatformIAM          InvariantID = "PLATFORM-IAM-001"
	InvariantPlatformBilling      InvariantID = "PLATFORM-BILLING-001"
	InvariantPlatformPolicy       InvariantID = "PLATFORM-POLICY-001"
	InvariantPlatformRegistry     InvariantID = "PLATFORM-REGISTRY-001"
	InvariantPlatformNotification InvariantID = "PLATFORM-NOTIFICATION-001"
	InvariantPlatformRuntime      InvariantID = "PLATFORM-RUNTIME-001"
	InvariantPlatformSecurity     InvariantID = "PLATFORM-SECURITY-001"
	InvariantPlatformRelease      InvariantID = "PLATFORM-RELEASE-001"
)

type ArtifactDigest struct {
	Name         string  `json:"name"`
	ArtifactType string  `json:"artifact_type"`
	Digest       string  `json:"digest"`
	SourceURI    *string `json:"source_uri"`
}

type Approval struct {
	Owner      string     `json:"owner"`
	Role       string     `json:"role"`
	Result     Result     `json:"result"`
	ApprovedAt *time.Time `json:"approved_at"`
	Comment    *string    `json:"comment"`
}

type ProductInvariantCoverage struct {
	InvariantID     string   `json:"invariant_id"`
	ProductArea     string   `json:"product_area"`
	Result          Result   `json:"result"`
	EvidenceItemIDs []string `json:"evidence_item_ids"`
	MissingReason   *string  `json:"missing_reason"`
}

type BundleSummary struct {
	BundleID           string    `json:"bundle_id"`
	SourceCommit       string    `json:"source_commit"`
	ReleaseBranch      *string   `json:"release_branch"`
	EnvironmentProfile string    `json:"environment_profile"`
	ProductScope       string    `json:"product_scope"`
	ChangeSummary      string    `json:"change_summary"`
	GateState          Result    `json:"gate_state"`
	ResidualRisk       *string   `json:"residual_risk"`
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
}

type Bundle struct {
	BundleSummary
	ArtifactDigests []ArtifactDigest           `json:"artifact_digests"`
	MigrationStatus *string                    `json:"migration_status"`
	CapacityPosture *string                    `json:"capacity_posture"`
	RollbackPlan    *string                    `json:"rollback_plan"`
	CorrelationIDs  []string                   `json:"correlation_ids"`
	Approvals       []Approval                 `json:"approvals"`
	Invariants      []ProductInvariantCoverage `json:"invariants"`
	Items           []Item                     `json:"items"`
}

type Item struct {
	EvidenceItemID   string         `json:"evidence_item_id"`
	BundleID         string         `json:"-"`
	EvidenceType     string         `json:"evidence_type"`
	Producer         string         `json:"producer"`
	SourceURI        *string        `json:"source_uri"`
	ArtifactPath     *string        `json:"artifact_path"`
	Result           Result         `json:"result"`
	StartedAt        *time.Time     `json:"started_at"`
	CompletedAt      *time.Time     `json:"completed_at"`
	CorrelationID    *string        `json:"correlation_id"`
	Owner            string         `json:"owner"`
	RetentionClass   string         `json:"retention_class"`
	ProvesInvariants []string       `json:"proves_invariants"`
	Details          map[string]any `json:"details"`
}

type GateStatus struct {
	GateID          string   `json:"gate_id"`
	Label           string   `json:"label"`
	Result          Result   `json:"result"`
	Owner           string   `json:"owner"`
	EvidenceItemIDs []string `json:"evidence_item_ids"`
	MissingReason   *string  `json:"missing_reason"`
}

type CreateBundleInput struct {
	SourceCommit       string
	ReleaseBranch      *string
	EnvironmentProfile string
	ProductScope       string
	ChangeSummary      string
	ArtifactDigests    []ArtifactDigest
	MigrationStatus    *string
	CapacityPosture    *string
	ResidualRisk       *string
	RollbackPlan       *string
	CorrelationIDs     []string
	CreatedByUserID    *string
}

type RecordItemInput struct {
	BundleID         string
	EvidenceType     string
	Producer         string
	SourceURI        *string
	ArtifactPath     *string
	Result           Result
	StartedAt        *time.Time
	CompletedAt      *time.Time
	CorrelationID    *string
	Owner            string
	RetentionClass   string
	ProvesInvariants []string
	Details          map[string]any
}

type RecordInvariantInput struct {
	BundleID        string
	InvariantID     string
	ProductArea     string
	Result          Result
	EvidenceItemIDs []string
	MissingReason   *string
}
