package proof

import (
	"time"

	"github.com/tidbcloud/controlplane9/internal/host"
	cptilt "github.com/tidbcloud/controlplane9/internal/tilt"
)

const (
	SchemaVersion = "cp9.proof/v1alpha1"

	StatusPassed       = "passed"
	StatusFailed       = "failed"
	StatusPartial      = "partial"
	StatusNotCollected = "not_collected"
)

// Summary is the legacy machine-readable CP9 evidence manifest projected by status.
type Summary struct {
	SchemaVersion string        `json:"schema_version"`
	Status        string        `json:"status"`
	FailurePhase  string        `json:"failure_phase,omitempty"`
	Session       Session       `json:"session"`
	CP9           CP9Metadata   `json:"cp9"`
	StartedAt     time.Time     `json:"started_at"`
	CompletedAt   time.Time     `json:"completed_at"`
	Stages        []Stage       `json:"stages"`
	Tilt          *Tilt         `json:"tilt,omitempty"`
	ImageSource   *ImageSource  `json:"image_source,omitempty"`
	SourceBacked  *SourceBacked `json:"source_backed,omitempty"`
	ProductRoute  *ProductRoute `json:"product_route,omitempty"`
	Smoke         *Smoke        `json:"smoke,omitempty"`
	Trains        []Train       `json:"trains"`
	Cleanup       *Cleanup      `json:"cleanup,omitempty"`
	Timing        Timing        `json:"timing"`
	ArtifactPaths ArtifactPaths `json:"artifact_paths"`
}

type Session struct {
	Name          string               `json:"name"`
	Persona       string               `json:"persona"`
	Owner         string               `json:"owner,omitempty"`
	Account       string               `json:"account,omitempty"`
	Region        string               `json:"region,omitempty"`
	HostMode      string               `json:"host_mode,omitempty"`
	HostExecution *host.ExecutionFacts `json:"host_execution,omitempty"`
	ConfigPath    string               `json:"config_path,omitempty"`
	ConfigDigest  string               `json:"config_digest,omitempty"`
	SourceCommits map[string]string    `json:"source_commits,omitempty"`
}

type CP9Metadata struct {
	Commit string `json:"commit,omitempty"`
}

type Stage struct {
	Name         string    `json:"name"`
	Status       string    `json:"status"`
	Message      string    `json:"message,omitempty"`
	ArtifactPath string    `json:"artifact_path,omitempty"`
	FailureClass string    `json:"failure_class,omitempty"`
	StartedAt    time.Time `json:"started_at,omitzero"`
	CompletedAt  time.Time `json:"completed_at,omitzero"`
	DurationMS   int64     `json:"duration_ms,omitempty"`
}

type Tilt struct {
	Status              string               `json:"status"`
	Endpoint            string               `json:"endpoint,omitempty"`
	Namespace           string               `json:"namespace,omitempty"`
	ReadyResources      int                  `json:"ready_resources,omitempty"`
	TotalResources      int                  `json:"total_resources,omitempty"`
	NotReadyResources   []string             `json:"not_ready_resources,omitempty"`
	KubeAPITunnelRepair *cptilt.TunnelRepair `json:"kube_api_tunnel_repair,omitempty"`
	ArtifactPath        string               `json:"artifact_path,omitempty"`
}

type ImageSource struct {
	Status                  string                               `json:"status"`
	Mode                    string                               `json:"mode,omitempty"`
	SharedBaseServices      []string                             `json:"shared_base_services,omitempty"`
	PremiumServices         []string                             `json:"premium_services,omitempty"`
	StarterServices         []string                             `json:"starter_services,omitempty"`
	DedicatedServices       []string                             `json:"dedicated_services,omitempty"`
	SourceBuildServices     []string                             `json:"source_build_services,omitempty"`
	StagingImageServices    []string                             `json:"staging_image_services,omitempty"`
	AlwaysLocalStubServices []string                             `json:"always_local_stub_services,omitempty"`
	GatedServices           []string                             `json:"gated_services,omitempty"`
	ServiceClassifications  map[string]ImageSourceClassification `json:"service_classifications,omitempty"`
	Images                  map[string]string                    `json:"images,omitempty"`
	ArtifactPath            string                               `json:"artifact_path,omitempty"`
}

type ImageSourceClassification struct {
	Class         string `json:"class"`
	Mode          string `json:"mode,omitempty"`
	SelectedImage string `json:"selected_image,omitempty"`
	StagingImage  string `json:"staging_image,omitempty"`
	SourceRepo    string `json:"source_repo,omitempty"`
	SourceMain    string `json:"source_main,omitempty"`
	SourceMode    string `json:"source_mode,omitempty"`
	BackendKind   string `json:"backend_kind,omitempty"`
	BackendScope  string `json:"backend_scope,omitempty"`
	SupportStatus string `json:"support_status,omitempty"`
	Evidence      string `json:"evidence,omitempty"`
	Reason        string `json:"reason,omitempty"`
}

type SourceBacked struct {
	Status            string                        `json:"status"`
	ImageSourcePath   string                        `json:"image_source_path,omitempty"`
	Groups            []SourceBackedGroup           `json:"groups,omitempty"`
	SelectedServices  []SourceBackedService         `json:"selected_services,omitempty"`
	StarterActivation *StarterActivationEvidence    `json:"starter_activation,omitempty"`
	StarterStatus     *StarterStatusEvidence        `json:"starter_status,omitempty"`
	AdvisoryFindings  []SourceBackedAdvisoryFinding `json:"advisory_findings,omitempty"`
}

type SourceBackedGroup struct {
	BackendKind  string   `json:"backend_kind"`
	BackendScope string   `json:"backend_scope,omitempty"`
	Mode         string   `json:"mode,omitempty"`
	Services     []string `json:"services"`
}

type SourceBackedService struct {
	Service       string `json:"service"`
	Mode          string `json:"mode,omitempty"`
	BackendKind   string `json:"backend_kind,omitempty"`
	BackendScope  string `json:"backend_scope,omitempty"`
	SelectedImage string `json:"selected_image,omitempty"`
	StagingImage  string `json:"staging_image,omitempty"`
	SourceRepo    string `json:"source_repo,omitempty"`
	SourceMain    string `json:"source_main,omitempty"`
	SourceMode    string `json:"source_mode,omitempty"`
	SupportStatus string `json:"support_status,omitempty"`
	Evidence      string `json:"evidence,omitempty"`
}

type StarterActivationEvidence struct {
	Status               string                       `json:"status"`
	ArtifactPath         string                       `json:"artifact_path,omitempty"`
	SourceSummaryPath    string                       `json:"source_summary_path,omitempty"`
	SourceSummaryLoaded  bool                         `json:"source_summary_loaded"`
	SourceBuildServices  []string                     `json:"source_build_services,omitempty"`
	ActivationImages     []StarterActivationImage     `json:"activation_images,omitempty"`
	SelectedSourceImages []StarterSelectedSourceImage `json:"selected_source_images,omitempty"`
}

type StarterActivationImage struct {
	Service string `json:"service"`
	Image   string `json:"image"`
	Source  string `json:"source"`
}

type StarterSelectedSourceImage struct {
	Service    string `json:"service"`
	Image      string `json:"image"`
	Namespace  string `json:"namespace"`
	Deployment string `json:"deployment"`
	Container  string `json:"container"`
}

type StarterStatusEvidence struct {
	Status            string                       `json:"status"`
	ArtifactPath      string                       `json:"artifact_path,omitempty"`
	State             string                       `json:"state,omitempty"`
	Session           string                       `json:"session,omitempty"`
	Persona           string                       `json:"persona,omitempty"`
	RemoteEKSCluster  string                       `json:"remote_eks_cluster,omitempty"`
	Message           string                       `json:"message,omitempty"`
	SourceImageChecks []StarterStatusCheckEvidence `json:"source_image_checks,omitempty"`
}

type StarterStatusCheckEvidence struct {
	Name    string `json:"name"`
	Status  string `json:"status"`
	Message string `json:"message,omitempty"`
}

type SourceBackedAdvisoryFinding struct {
	Source       string `json:"source"`
	Service      string `json:"service,omitempty"`
	Status       string `json:"status"`
	Message      string `json:"message,omitempty"`
	ArtifactPath string `json:"artifact_path,omitempty"`
}

type ProductRoute struct {
	Status       string `json:"status"`
	PublicRoute  string `json:"public_route,omitempty"`
	KongRoute    string `json:"kong_route,omitempty"`
	BackendRoute string `json:"backend_route,omitempty"`
	Endpoint     string `json:"endpoint,omitempty"`
	SQL          *SQL   `json:"sql,omitempty"`
}

type Smoke struct {
	SchemaVersion string         `json:"schema_version"`
	Status        string         `json:"status"`
	ArtifactPath  string         `json:"artifact_path,omitempty"`
	Surfaces      []SmokeSurface `json:"surfaces,omitempty"`
}

type SmokeSurface struct {
	Name         string `json:"name"`
	Status       string `json:"status"`
	ArtifactDir  string `json:"artifact_dir,omitempty"`
	LogPath      string `json:"log_path,omitempty"`
	Message      string `json:"message,omitempty"`
	FailureClass string `json:"failure_class,omitempty"`
}

type SQL struct {
	Path   string `json:"path,omitempty"`
	Result string `json:"result,omitempty"`
}

type Train struct {
	Name               string          `json:"name"`
	Group              string          `json:"group,omitempty"`
	Status             string          `json:"status"`
	Scenario           string          `json:"scenario,omitempty"`
	ArtifactDir        string          `json:"artifact_dir,omitempty"`
	RequestCount       int             `json:"request_count,omitempty"`
	FailedRequests     []FailedRequest `json:"failed_requests,omitempty"`
	KeyRequests        []Request       `json:"key_requests,omitempty"`
	CreatedResourceIDs []string        `json:"created_resource_ids,omitempty"`
	Endpoint           *Endpoint       `json:"endpoint,omitempty"`
	SQL                *SQL            `json:"sql,omitempty"`
	Message            string          `json:"message,omitempty"`
	StartedAt          time.Time       `json:"started_at,omitzero"`
	CompletedAt        time.Time       `json:"completed_at,omitzero"`
	DurationMS         int64           `json:"duration_ms,omitempty"`
}

type Request struct {
	ID             string    `json:"id,omitempty"`
	OperationID    string    `json:"operation_id,omitempty"`
	Method         string    `json:"method,omitempty"`
	HTTPStatus     string    `json:"http_status,omitempty"`
	ExpectedStatus string    `json:"expected_status,omitempty"`
	CurlExitCode   int       `json:"curl_exit_code,omitempty"`
	URL            string    `json:"url,omitempty"`
	TraceID        string    `json:"trace_id,omitempty"`
	Purpose        string    `json:"purpose,omitempty"`
	StartedAt      time.Time `json:"started_at,omitzero"`
	CompletedAt    time.Time `json:"completed_at,omitzero"`
	DurationMS     int64     `json:"duration_ms,omitempty"`
}

type FailedRequest struct {
	ID           string `json:"id,omitempty"`
	OperationID  string `json:"operation_id,omitempty"`
	HTTPStatus   string `json:"http_status,omitempty"`
	TraceID      string `json:"trace_id,omitempty"`
	FailureClass string `json:"failure_class,omitempty"`
	Message      string `json:"message,omitempty"`
}

type Endpoint struct {
	Host string `json:"host,omitempty"`
	Port int    `json:"port,omitempty"`
}

type Cleanup struct {
	Status               string   `json:"status"`
	WorkflowURL          string   `json:"workflow_url,omitempty"`
	WorkflowResult       string   `json:"workflow_result,omitempty"`
	DirectZero           bool     `json:"direct_zero,omitempty"`
	StaleTagWarnings     []string `json:"stale_tag_warnings,omitempty"`
	FailurePhase         string   `json:"failure_phase,omitempty"`
	FallbackResult       string   `json:"fallback_result,omitempty"`
	FinalSurvivorVerdict string   `json:"final_survivor_verdict,omitempty"`
	ArtifactPath         string   `json:"artifact_path,omitempty"`
}

type ArtifactPaths struct {
	JSON     string `json:"json"`
	Markdown string `json:"markdown"`
	Timing   string `json:"timing"`
}

type Timing struct {
	SchemaVersion string         `json:"schema_version"`
	Status        string         `json:"status"`
	StartedAt     time.Time      `json:"started_at,omitzero"`
	CompletedAt   time.Time      `json:"completed_at,omitzero"`
	DurationMS    int64          `json:"duration_ms,omitempty"`
	Records       []TimingRecord `json:"records,omitempty"`
}

type TimingRecord struct {
	Name         string    `json:"name"`
	Kind         string    `json:"kind"`
	Status       string    `json:"status"`
	StartedAt    time.Time `json:"started_at,omitzero"`
	CompletedAt  time.Time `json:"completed_at,omitzero"`
	DurationMS   int64     `json:"duration_ms,omitempty"`
	ArtifactPath string    `json:"artifact_path,omitempty"`
	Message      string    `json:"message,omitempty"`
}
