package cluster

import (
	"fmt"
	"slices"
	"strings"
	"time"

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

// StatusResult holds the output of `cp9 status`.
type StatusResult struct {
	Status            string           `json:"status"`
	Message           string           `json:"message,omitempty"`
	ClusterName       string           `json:"cluster_name"`
	SessionID         string           `json:"session_id"`
	SessionName       string           `json:"session_name,omitempty"`
	Persona           string           `json:"persona,omitempty"`
	HostMode          string           `json:"host_mode,omitempty"`
	Owner             string           `json:"owner,omitempty"`
	TTL               string           `json:"ttl,omitempty"`
	StateDir          string           `json:"state_dir,omitempty"`
	Complete          bool             `json:"complete"`
	LifecycleComplete bool             `json:"lifecycle_complete"`
	Lifecycle         StepName         `json:"lifecycle_state,omitempty"`
	ResumeAt          StepName         `json:"resume_at,omitempty"`
	Steps             []StepInfo       `json:"steps"`
	Artifacts         *StatusArtifacts `json:"artifacts,omitempty"`
	Layers            *StatusLayers    `json:"layers,omitempty"`
	Tilt              *StatusTilt      `json:"tilt,omitempty"`
	Cost              *StatusCost      `json:"cost,omitempty"`
	CreatedAt         time.Time        `json:"created_at"`
	UpdatedAt         time.Time        `json:"updated_at"`
}

// StatusLayers separates lifecycle state from runtime, product, proof, and
// cleanup evidence so a ready lifecycle is not mistaken for a proven product.
type StatusLayers struct {
	Lifecycle    StatusLifecycleLayer     `json:"lifecycle"`
	Host         StatusHostLayer          `json:"host"`
	DedicatedGCP *StatusDedicatedGCPLayer `json:"dedicated_gcp,omitempty"`
	ImageSource  *StatusImageSourceLayer  `json:"image_source,omitempty"`
	Tilt         *StatusTilt              `json:"tilt,omitempty"`
	UI           *StatusUILayer           `json:"ui,omitempty"`
	Starter      *StatusStarterLayer      `json:"starter,omitempty"`
	O11Y         *StatusO11YLayer         `json:"o11y,omitempty"`
	ProductRoute *StatusProductRouteLayer `json:"product_route,omitempty"`
	Proof        *StatusProofLayer        `json:"proof,omitempty"`
	Cleanup      *StatusCleanupLayer      `json:"cleanup,omitempty"`
}

type StatusO11YDimension struct {
	Status       string `json:"status"`
	EvidencePath string `json:"evidence_path,omitempty"`
	Message      string `json:"message,omitempty"`
}

// StatusO11YLayer projects durable proof evidence without probing or mutating
// the live O11Y platform.
type StatusO11YLayer struct {
	Status              string                         `json:"status"`
	Platform            StatusO11YDimension            `json:"platform"`
	RoutingMapping      map[string]StatusO11YDimension `json:"routing_mapping,omitempty"`
	ACS                 map[string]StatusO11YDimension `json:"acs,omitempty"`
	AgentCR             map[string]StatusO11YDimension `json:"agent_cr,omitempty"`
	AgentWorkload       map[string]StatusO11YDimension `json:"agent_workload,omitempty"`
	MetricsWriteQuery   map[string]StatusO11YDimension `json:"metrics_write_query,omitempty"`
	NamespaceNegative   map[string]StatusO11YDimension `json:"namespace_negative,omitempty"`
	InterruptedRecovery map[string]StatusO11YDimension `json:"interrupted_recovery,omitempty"`
	Idempotency         map[string]StatusO11YDimension `json:"idempotency,omitempty"`
	Cleanup             map[string]StatusO11YDimension `json:"cleanup,omitempty"`
	PublicWriteNegative StatusO11YDimension            `json:"public_write_negative"`
	LogsBackend         string                         `json:"logs_backend"`
	Alerts              string                         `json:"alerts"`
	DrHouse             string                         `json:"dr_house"`
	Message             string                         `json:"message,omitempty"`
}

// StatusUILayer reports the mandatory Remote Dev full UI as independent
// delivery, shared-auth, and identity dimensions.
type StatusUILayer struct {
	Status            string     `json:"status"`
	URL               string     `json:"url,omitempty"`
	APIURL            string     `json:"api_url,omitempty"`
	LoginMethod       string     `json:"login_method,omitempty"`
	LoginEmail        string     `json:"login_email,omitempty"`
	LoginHelp         string     `json:"login_help,omitempty"`
	Image             string     `json:"image,omitempty"`
	UIStaticReady     bool       `json:"ui_static_ready"`
	UIAuthReady       bool       `json:"ui_auth_ready"`
	UIIdentityReady   bool       `json:"ui_identity_ready"`
	SessionOwnedReady bool       `json:"session_owned_ready"`
	UIReady           bool       `json:"ui_ready"`
	BrowserAcceptance string     `json:"browser_acceptance"`
	BrowserStage      string     `json:"browser_stage,omitempty"`
	BrowserPath       string     `json:"browser_path,omitempty"`
	BrowserCheckedAt  *time.Time `json:"browser_checked_at,omitempty"`
	StaticMessage     string     `json:"static_message,omitempty"`
	AuthMessage       string     `json:"auth_message,omitempty"`
	IdentityMessage   string     `json:"identity_message,omitempty"`
	BrowserMessage    string     `json:"browser_message,omitempty"`
	EvidencePath      string     `json:"evidence_path,omitempty"`
	BrowserEvidence   string     `json:"browser_evidence_path,omitempty"`
	Message           string     `json:"message,omitempty"`
}

// StatusStarterLayer reports persisted Starter EKS connection facts without
// probing or changing EKS access.
type StatusStarterLayer struct {
	Status     string `json:"status"`
	Cluster    string `json:"cluster,omitempty"`
	Region     string `json:"region,omitempty"`
	Profile    string `json:"profile,omitempty"`
	Kubeconfig string `json:"kubeconfig,omitempty"`
	Context    string `json:"context,omitempty"`
	Message    string `json:"message,omitempty"`
}

type StatusLifecycleLayer struct {
	Status   string   `json:"status"`
	State    StepName `json:"state,omitempty"`
	ResumeAt StepName `json:"resume_at,omitempty"`
	Message  string   `json:"message,omitempty"`
}

type StatusHostLayer struct {
	Status    string               `json:"status"`
	Mode      string               `json:"mode,omitempty"`
	Execution *host.ExecutionFacts `json:"execution,omitempty"`
}

// StatusDedicatedGCPLayer reports the independently persisted GCP host and
// remote Tilt runtime without conflating either with Product readiness.
type StatusDedicatedGCPLayer struct {
	DedicatedGCPPlan

	Status              string               `json:"status"`
	InstanceName        string               `json:"instance_name,omitempty"`
	PublicIP            string               `json:"public_ip,omitempty"`
	ServiceAccountEmail string               `json:"service_account_email,omitempty"`
	KubeconfigPath      string               `json:"kubeconfig_path,omitempty"`
	DedicatedAPI        string               `json:"dedicated_api,omitempty"`
	Execution           *host.ExecutionFacts `json:"execution,omitempty"`
	Tilt                *StatusTilt          `json:"tilt,omitempty"`
	Message             string               `json:"message,omitempty"`
}

// DedicatedGCPPlan is the non-secret config/path contract shared by dry-run
// and status output.
type DedicatedGCPPlan struct {
	SeedProjectID      string `json:"seed_project_id"`
	DataplaneProjectID string `json:"dataplane_project_id"`
	Region             string `json:"region"`
	Zone               string `json:"zone"`
	MachineType        string `json:"machine_type"`
	ModulePath         string `json:"module_path"`
	WorkDir            string `json:"work_dir"`
	PlanPath           string `json:"plan_path"`
}

type StatusImageSourceLayer 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"`
	SummaryPath             string                               `json:"summary_path,omitempty"`
	Message                 string                               `json:"message,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 StatusProductRouteLayer struct {
	Status             string              `json:"status"`
	PublicOpenAPIRoute string              `json:"public_openapi_route,omitempty"`
	KongRoute          string              `json:"kong_route,omitempty"`
	BackendRoute       string              `json:"backend_route,omitempty"`
	SQLEndpoint        string              `json:"sql_endpoint,omitempty"`
	SQL                *StatusSQLReadiness `json:"sql,omitempty"`
	SourceTiDBIDs      []string            `json:"source_tidb_ids,omitempty"`
	RestoredTiDBIDs    []string            `json:"restored_tidb_ids,omitempty"`
	Message            string              `json:"message,omitempty"`
}

type StatusSQLReadiness struct {
	Ready  bool   `json:"ready"`
	Path   string `json:"path,omitempty"`
	Result string `json:"result,omitempty"`
}

type StatusProofLayer struct {
	Status           string    `json:"status"`
	FailurePhase     string    `json:"failure_phase,omitempty"`
	LastFailureClass string    `json:"last_failure_class,omitempty"`
	SummaryPath      string    `json:"summary_path,omitempty"`
	ReportPath       string    `json:"report_path,omitempty"`
	CompletedAt      time.Time `json:"completed_at,omitzero"`
	Message          string    `json:"message,omitempty"`
}

type StatusCleanupLayer struct {
	Status           string   `json:"status"`
	DirectZero       bool     `json:"direct_zero,omitempty"`
	WorkflowURL      string   `json:"workflow_url,omitempty"`
	WorkflowResult   string   `json:"workflow_result,omitempty"`
	FailurePhase     string   `json:"failure_phase,omitempty"`
	FallbackResult   string   `json:"fallback_result,omitempty"`
	FinalVerdict     string   `json:"final_verdict,omitempty"`
	FinalSurvivors   int      `json:"final_survivors,omitempty"`
	ArtifactPath     string   `json:"artifact_path,omitempty"`
	StaleTagWarnings []string `json:"stale_tag_warnings,omitempty"`
	Message          string   `json:"message,omitempty"`
}

// StatusArtifacts names durable files and directories agents need when debugging.
type StatusArtifacts struct {
	ResolvedSession       string `json:"resolved_session,omitempty"`
	TerraformPlan         string `json:"terraform_plan,omitempty"`
	GCPTerraformPlan      string `json:"gcp_terraform_plan,omitempty"`
	GCPTerraformState     string `json:"gcp_terraform_state,omitempty"`
	GCPTerraformOutputs   string `json:"gcp_terraform_outputs,omitempty"`
	GCPRegionalHost       string `json:"gcp_regional_host,omitempty"`
	GCPRegionalKubeconfig string `json:"gcp_regional_kubeconfig,omitempty"`
	MetadbSeedReport      string `json:"metadb_seed_report,omitempty"`
	ContextDir            string `json:"context_dir,omitempty"`
	Tiltfile              string `json:"tiltfile,omitempty"`
	RuntimePlan           string `json:"runtime_plan,omitempty"`
	StarterRegionalSmoke  string `json:"starter_regional_smoke,omitempty"`
	DestroyDir            string `json:"destroy_dir,omitempty"`
}

// StatusTilt summarizes the persisted Tilt runtime contract for one session.
type StatusTilt struct {
	RuntimeID         string            `json:"runtime_id,omitempty"`
	Status            string            `json:"status"`
	Mode              string            `json:"mode,omitempty"`
	Controller        string            `json:"controller,omitempty"`
	Running           bool              `json:"running"`
	Endpoint          string            `json:"endpoint,omitempty"`
	URL               string            `json:"url,omitempty"`
	LogPath           string            `json:"log_path,omitempty"`
	ReadyResources    int               `json:"ready_resources,omitempty"`
	TotalResources    int               `json:"total_resources,omitempty"`
	NotReadyResources []string          `json:"not_ready_resources,omitempty"`
	FailedResources   []string          `json:"failed_resources,omitempty"`
	ReadinessError    string            `json:"readiness_error,omitempty"`
	Retryable         bool              `json:"retryable,omitempty"`
	Tunnels           []StatusTunnel    `json:"tunnels,omitempty"`
	Message           string            `json:"message,omitempty"`
	FailureReasons    map[string]string `json:"-"`
}

// StatusTunnel reports one local tunnel supervisor owned by a remote session.
type StatusTunnel struct {
	Role           string `json:"role"`
	PID            int    `json:"pid"`
	State          string `json:"state"`
	Attempts       int    `json:"attempts,omitempty"`
	LastFailure    string `json:"last_failure,omitempty"`
	ActionRequired bool   `json:"action_required,omitempty"`
}

// StatusCost reports session cost or why cost is unavailable.
type StatusCost struct {
	Status  string `json:"status"`
	Message string `json:"message,omitempty"`
}

// StepInfo is a summary of a single step for status display.
type StepInfo struct {
	Name     StepName      `json:"name"`
	Status   StepStatus    `json:"status"`
	Duration time.Duration `json:"duration,omitempty"`
	Error    string        `json:"error,omitempty"`
}

// FormatText implements model.TextFormatter.
func (r *StatusResult) FormatText() string {
	var b strings.Builder

	fmt.Fprintf(&b, "Cluster: %s (session: %s)\n", r.ClusterName, r.SessionID)
	if r.SessionName != "" {
		fmt.Fprintf(&b, "Name:    %s\n", r.SessionName)
	}
	if r.Persona != "" {
		fmt.Fprintf(&b, "Persona: %s\n", r.Persona)
	}
	if r.HostMode != "" {
		fmt.Fprintf(&b, "Host:    %s\n", r.HostMode)
	}
	if r.Owner != "" {
		fmt.Fprintf(&b, "Owner:   %s\n", r.Owner)
	}
	if r.TTL != "" {
		fmt.Fprintf(&b, "TTL:     %s\n", r.TTL)
	}
	if r.StateDir != "" {
		fmt.Fprintf(&b, "StateDir: %s\n", r.StateDir)
	}
	fmt.Fprintf(&b, "Status:  %s\n", firstNonEmptyStatusText(r.Status, "unknown"))
	if r.Message != "" {
		fmt.Fprintf(&b, "Message: %s\n", r.Message)
	}

	if r.Lifecycle != "" {
		fmt.Fprintf(&b, "State:   %s\n", r.Lifecycle)
	}

	fmt.Fprintf(&b, "Created: %s\n", r.CreatedAt.Format(time.RFC3339))
	fmt.Fprintf(&b, "Updated: %s\n\n", r.UpdatedAt.Format(time.RFC3339))

	if r.Layers != nil {
		b.WriteString("Layers:\n")
		fmt.Fprintf(&b, "  Lifecycle: %s", r.Layers.Lifecycle.Status)
		if r.Layers.Lifecycle.State != "" {
			fmt.Fprintf(&b, " state=%s", r.Layers.Lifecycle.State)
		}
		if r.Layers.Lifecycle.ResumeAt != "" {
			fmt.Fprintf(&b, " resume_at=%s", r.Layers.Lifecycle.ResumeAt)
		}
		if r.Layers.Lifecycle.Message != "" {
			fmt.Fprintf(&b, " (%s)", r.Layers.Lifecycle.Message)
		}
		b.WriteString("\n")
		fmt.Fprintf(&b, "  Host:      %s", firstNonEmptyStatusText(r.Layers.Host.Mode, r.Layers.Host.Status))
		if r.Layers.Host.Mode != "" && r.Layers.Host.Status != "" && r.Layers.Host.Status != "configured" {
			fmt.Fprintf(&b, " status=%s", r.Layers.Host.Status)
		}
		writeHostExecutionFacts(&b, r.Layers.Host.Execution)
		b.WriteString("\n")
		if r.Layers.DedicatedGCP != nil {
			fmt.Fprintf(&b, "  DedicatedGCP: %s", r.Layers.DedicatedGCP.Status)
			writeStatusPart(&b, "project", r.Layers.DedicatedGCP.SeedProjectID)
			writeStatusPart(&b, "dataplane_project", r.Layers.DedicatedGCP.DataplaneProjectID)
			writeStatusPart(&b, "location", strings.Trim(r.Layers.DedicatedGCP.Region+"/"+r.Layers.DedicatedGCP.Zone, "/"))
			writeStatusPart(&b, "machine_type", r.Layers.DedicatedGCP.MachineType)
			writeStatusPart(&b, "plan", r.Layers.DedicatedGCP.PlanPath)
			writeStatusPart(&b, "instance", r.Layers.DedicatedGCP.InstanceName)
			writeStatusPart(&b, "public_ip", r.Layers.DedicatedGCP.PublicIP)
			writeStatusPart(&b, "kubeconfig", r.Layers.DedicatedGCP.KubeconfigPath)
			writeStatusPart(&b, "dedicated_api", r.Layers.DedicatedGCP.DedicatedAPI)
			writeHostExecutionFacts(&b, r.Layers.DedicatedGCP.Execution)
			if r.Layers.DedicatedGCP.Tilt != nil {
				writeStatusPart(&b, "tilt", r.Layers.DedicatedGCP.Tilt.Status)
				writeStatusPart(&b, "tilt_endpoint", r.Layers.DedicatedGCP.Tilt.Endpoint)
			}
			if r.Layers.DedicatedGCP.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.DedicatedGCP.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.ImageSource != nil {
			fmt.Fprintf(&b, "  ImageSource: %s", r.Layers.ImageSource.Status)
			writeStatusPart(&b, "mode", r.Layers.ImageSource.Mode)
			writeStatusPart(&b, "summary", r.Layers.ImageSource.SummaryPath)
			writeStatusPart(&b, "source_build", strings.Join(r.Layers.ImageSource.SourceBuildServices, ","))
			writeStatusPart(&b, "staging_image", strings.Join(r.Layers.ImageSource.StagingImageServices, ","))
			writeStatusPart(&b, "always_local_stub", strings.Join(r.Layers.ImageSource.AlwaysLocalStubServices, ","))
			if r.Layers.ImageSource.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.ImageSource.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.Tilt != nil {
			fmt.Fprintf(&b, "  Tilt:      %s", r.Layers.Tilt.Status)
			writeStatusPart(&b, "runtime", r.Layers.Tilt.RuntimeID)
			if r.Layers.Tilt.Mode != "" {
				fmt.Fprintf(&b, " mode=%s", r.Layers.Tilt.Mode)
			}
			if r.Layers.Tilt.Endpoint != "" {
				fmt.Fprintf(&b, " endpoint=%s", r.Layers.Tilt.Endpoint)
			}
			writeStatusPart(&b, "url", r.Layers.Tilt.URL)
			if r.Layers.Tilt.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.Tilt.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.UI != nil {
			fmt.Fprintf(&b, "  UI:        %s", r.Layers.UI.Status)
			writeStatusPart(&b, "url", r.Layers.UI.URL)
			writeStatusPart(&b, "api_url", r.Layers.UI.APIURL)
			writeStatusPart(&b, "login_method", r.Layers.UI.LoginMethod)
			writeStatusPart(&b, "login_email", r.Layers.UI.LoginEmail)
			writeStatusPart(&b, "login_help", r.Layers.UI.LoginHelp)
			writeStatusPart(&b, "browser_acceptance", r.Layers.UI.BrowserAcceptance)
			writeStatusPart(&b, "browser_stage", r.Layers.UI.BrowserStage)
			writeStatusPart(&b, "browser_path", r.Layers.UI.BrowserPath)
			if r.Layers.UI.BrowserCheckedAt != nil {
				writeStatusPart(&b, "browser_checked_at", r.Layers.UI.BrowserCheckedAt.Format(time.RFC3339))
			}
			fmt.Fprintf(
				&b,
				" static=%t auth=%t identity=%t ready=%t",
				r.Layers.UI.UIStaticReady,
				r.Layers.UI.UIAuthReady,
				r.Layers.UI.UIIdentityReady,
				r.Layers.UI.UIReady,
			)
			writeStatusPart(&b, "evidence", r.Layers.UI.EvidencePath)
			if r.Layers.UI.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.UI.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.Starter != nil {
			fmt.Fprintf(&b, "  Starter:   %s", r.Layers.Starter.Status)
			writeStatusPart(&b, "cluster", r.Layers.Starter.Cluster)
			writeStatusPart(&b, "region", r.Layers.Starter.Region)
			writeStatusPart(&b, "profile", r.Layers.Starter.Profile)
			writeStatusPart(&b, "kubeconfig", r.Layers.Starter.Kubeconfig)
			writeStatusPart(&b, "context", r.Layers.Starter.Context)
			if r.Layers.Starter.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.Starter.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.O11Y != nil {
			fmt.Fprintf(&b, "  O11Y:     %s", r.Layers.O11Y.Status)
			writeStatusPart(&b, "platform", r.Layers.O11Y.Platform.Status)
			writeStatusPart(&b, "routing_mapping", formatStatusO11YDimensions(r.Layers.O11Y.RoutingMapping))
			writeStatusPart(&b, "acs", formatStatusO11YDimensions(r.Layers.O11Y.ACS))
			writeStatusPart(&b, "agent_cr", formatStatusO11YDimensions(r.Layers.O11Y.AgentCR))
			writeStatusPart(&b, "agent_workload", formatStatusO11YDimensions(r.Layers.O11Y.AgentWorkload))
			writeStatusPart(&b, "metrics_write_query", formatStatusO11YDimensions(r.Layers.O11Y.MetricsWriteQuery))
			writeStatusPart(&b, "namespace_negative", formatStatusO11YDimensions(r.Layers.O11Y.NamespaceNegative))
			writeStatusPart(&b, "public_write_negative", r.Layers.O11Y.PublicWriteNegative.Status)
			writeStatusPart(&b, "interrupted_recovery", formatStatusO11YDimensions(r.Layers.O11Y.InterruptedRecovery))
			writeStatusPart(&b, "idempotency", formatStatusO11YDimensions(r.Layers.O11Y.Idempotency))
			writeStatusPart(&b, "cleanup", formatStatusO11YDimensions(r.Layers.O11Y.Cleanup))
			writeStatusPart(&b, "logs_backend", r.Layers.O11Y.LogsBackend)
			writeStatusPart(&b, "alerts", r.Layers.O11Y.Alerts)
			writeStatusPart(&b, "dr_house", r.Layers.O11Y.DrHouse)
			if r.Layers.O11Y.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.O11Y.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.ProductRoute != nil {
			fmt.Fprintf(&b, "  Product:  %s", r.Layers.ProductRoute.Status)
			writeStatusPart(&b, "public_openapi_route", r.Layers.ProductRoute.PublicOpenAPIRoute)
			writeStatusPart(&b, "kong_route", r.Layers.ProductRoute.KongRoute)
			writeStatusPart(&b, "backend_route", r.Layers.ProductRoute.BackendRoute)
			writeStatusPart(&b, "sql_endpoint", r.Layers.ProductRoute.SQLEndpoint)
			writeStatusPart(&b, "source_tidb_ids", strings.Join(r.Layers.ProductRoute.SourceTiDBIDs, ","))
			writeStatusPart(&b, "restored_tidb_ids", strings.Join(r.Layers.ProductRoute.RestoredTiDBIDs, ","))
			if r.Layers.ProductRoute.SQL != nil {
				fmt.Fprintf(&b, " sql_ready=%t", r.Layers.ProductRoute.SQL.Ready)
			}
			if r.Layers.ProductRoute.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.ProductRoute.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.Proof != nil {
			fmt.Fprintf(&b, "  Proof:    %s", r.Layers.Proof.Status)
			writeStatusPart(&b, "summary", r.Layers.Proof.SummaryPath)
			writeStatusPart(&b, "report", r.Layers.Proof.ReportPath)
			writeStatusPart(&b, "failure_phase", r.Layers.Proof.FailurePhase)
			writeStatusPart(&b, "last_failure_class", r.Layers.Proof.LastFailureClass)
			if r.Layers.Proof.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.Proof.Message)
			}
			b.WriteString("\n")
		}
		if r.Layers.Cleanup != nil {
			fmt.Fprintf(&b, "  Cleanup:  %s", r.Layers.Cleanup.Status)
			fmt.Fprintf(&b, " direct_zero=%t", r.Layers.Cleanup.DirectZero)
			writeStatusPart(&b, "final_verdict", r.Layers.Cleanup.FinalVerdict)
			if r.Layers.Cleanup.FinalSurvivors > 0 {
				fmt.Fprintf(&b, " final_survivors=%d", r.Layers.Cleanup.FinalSurvivors)
			}
			writeStatusPart(&b, "artifact", r.Layers.Cleanup.ArtifactPath)
			writeStatusPart(&b, "workflow_result", r.Layers.Cleanup.WorkflowResult)
			writeStatusPart(&b, "failure_phase", r.Layers.Cleanup.FailurePhase)
			writeStatusPart(&b, "fallback_result", r.Layers.Cleanup.FallbackResult)
			if r.Layers.Cleanup.Message != "" {
				fmt.Fprintf(&b, " (%s)", r.Layers.Cleanup.Message)
			}
			b.WriteString("\n")
		}
		b.WriteString("\n")
	}

	if r.Artifacts != nil {
		b.WriteString("Artifacts:\n")
		writeArtifactLine(&b, "resolved_session", r.Artifacts.ResolvedSession)
		writeArtifactLine(&b, "terraform_plan", r.Artifacts.TerraformPlan)
		writeArtifactLine(&b, "gcp_terraform_plan", r.Artifacts.GCPTerraformPlan)
		writeArtifactLine(&b, "gcp_terraform_state", r.Artifacts.GCPTerraformState)
		writeArtifactLine(&b, "gcp_terraform_outputs", r.Artifacts.GCPTerraformOutputs)
		writeArtifactLine(&b, "gcp_regional_host", r.Artifacts.GCPRegionalHost)
		writeArtifactLine(&b, "gcp_regional_kubeconfig", r.Artifacts.GCPRegionalKubeconfig)
		writeArtifactLine(&b, "metadb_seed_report", r.Artifacts.MetadbSeedReport)
		writeArtifactLine(&b, "context_dir", r.Artifacts.ContextDir)
		writeArtifactLine(&b, "tiltfile", r.Artifacts.Tiltfile)
		writeArtifactLine(&b, "runtime_plan", r.Artifacts.RuntimePlan)
		writeArtifactLine(&b, "starter_regional_smoke", r.Artifacts.StarterRegionalSmoke)
		writeArtifactLine(&b, "destroy_dir", r.Artifacts.DestroyDir)
		b.WriteString("\n")
	}
	if r.Tilt != nil {
		fmt.Fprintf(&b, "Tilt:    %s", r.Tilt.Status)
		writeStatusPart(&b, "runtime", r.Tilt.RuntimeID)
		if r.Tilt.Mode != "" {
			fmt.Fprintf(&b, " mode=%s", r.Tilt.Mode)
		}
		writeStatusPart(&b, "controller", r.Tilt.Controller)
		if r.Tilt.Endpoint != "" {
			fmt.Fprintf(&b, " endpoint=%s", r.Tilt.Endpoint)
		}
		writeStatusPart(&b, "url", r.Tilt.URL)
		if r.Tilt.Message != "" {
			fmt.Fprintf(&b, " (%s)", r.Tilt.Message)
		}
		b.WriteString("\n")
		for _, tunnel := range r.Tilt.Tunnels {
			fmt.Fprintf(&b, "  Tunnel: role=%s state=%s pid=%d", tunnel.Role, tunnel.State, tunnel.PID)
			if tunnel.Attempts > 0 {
				fmt.Fprintf(&b, " attempts=%d", tunnel.Attempts)
			}
			if tunnel.LastFailure != "" {
				fmt.Fprintf(&b, " last_failure=%q", tunnel.LastFailure)
			}
			if tunnel.ActionRequired {
				b.WriteString(" action_required=true")
			}
			b.WriteString("\n")
		}
		b.WriteString("\n")
	}
	if r.Cost != nil {
		fmt.Fprintf(&b, "Cost:    %s", r.Cost.Status)
		if r.Cost.Message != "" {
			fmt.Fprintf(&b, " (%s)", r.Cost.Message)
		}
		b.WriteString("\n\n")
	}

	b.WriteString("Steps:\n")
	for _, s := range r.Steps {
		icon := statusIcon(s.Status)
		if s.Duration > 0 {
			fmt.Fprintf(&b, "  %s %-20s %s", icon, s.Name, s.Duration.Round(time.Millisecond))
		} else {
			fmt.Fprintf(&b, "  %s %-20s", icon, s.Name)
		}
		if s.Error != "" {
			fmt.Fprintf(&b, " (%s)", s.Error)
		}
		b.WriteString("\n")
	}

	return b.String()
}

func formatStatusO11YDimensions(dimensions map[string]StatusO11YDimension) string {
	keys := make([]string, 0, len(dimensions))
	for key := range dimensions {
		keys = append(keys, key)
	}
	slices.Sort(keys)
	parts := make([]string, 0, len(keys))
	for _, key := range keys {
		parts = append(parts, key+":"+dimensions[key].Status)
	}
	return strings.Join(parts, ",")
}

func writeStatusPart(b *strings.Builder, name, value string) {
	if strings.TrimSpace(value) == "" {
		return
	}
	fmt.Fprintf(b, " %s=%s", name, value)
}

func writeHostExecutionFacts(b *strings.Builder, facts *host.ExecutionFacts) {
	if facts == nil {
		return
	}
	writeStatusPart(b, "controller", facts.Controller)
	writeStatusPart(b, "workload_runtime", facts.WorkloadRuntime)
	writeStatusPart(b, "source_sync", facts.SourceSync)
	writeStatusPart(b, "source_sync_destination", facts.SourceSyncDestination)
	writeStatusPart(b, "module_proxy", facts.ModuleProxy)
	writeStatusPart(b, "docker_build", facts.DockerBuild)
	writeStatusPart(b, "image_import", facts.ImageImport)
	writeStatusPart(b, "k3d_runtime", facts.K3dRuntime)
	writeStatusPart(b, "kube_api_tunnel", facts.KubeAPITunnel)
	writeStatusPart(b, "local_kubeconfig_path", facts.LocalKubeconfigPath)
	writeStatusPart(b, "kube_context", facts.KubeContext)
	if facts.Remote != nil {
		writeStatusPart(b, "remote_state_dir", facts.Remote.RemoteStateDir)
		writeStatusPart(b, "remote_kubeconfig_path", facts.Remote.RemoteKubeconfigPath)
		writeStatusPart(b, "remote_instance_id", facts.Remote.InstanceID)
		writeStatusPart(b, "remote_public_dns", facts.Remote.PublicDNS)
		if facts.Remote.Image != nil {
			writeStatusPart(b, "remote_image_family", facts.Remote.Image.Family)
			writeStatusPart(b, "remote_image_instance_type", facts.Remote.Image.InstanceType)
			writeStatusPart(b, "remote_image_architecture", facts.Remote.Image.Architecture)
			writeStatusPart(b, "remote_image_parameter", facts.Remote.Image.Parameter)
			writeStatusPart(b, "remote_image_ami", facts.Remote.Image.AMI)
			writeStatusPart(b, "remote_image_region", facts.Remote.Image.Region)
			if !facts.Remote.Image.ResolvedAt.IsZero() {
				writeStatusPart(b, "remote_image_resolved_at", facts.Remote.Image.ResolvedAt.UTC().Format(time.RFC3339))
			}
		}
	}
}

func firstNonEmptyStatusText(values ...string) string {
	for _, value := range values {
		if strings.TrimSpace(value) != "" {
			return value
		}
	}
	return "unknown"
}

func writeArtifactLine(b *strings.Builder, name, path string) {
	if path == "" {
		return
	}
	fmt.Fprintf(b, "  %-18s %s\n", name+":", path)
}

// BuildStatus creates a StatusResult from a loaded State.
func BuildStatus(state *State) *StatusResult {
	var steps []StepInfo
	for _, name := range state.stepOrder() {
		info := StepInfo{Name: name, Status: StatusPending}
		if st, ok := state.Steps[name]; ok && st != nil {
			info.Status = st.Status
			info.Duration = st.Duration()
			info.Error = st.Error
		}
		steps = append(steps, info)
	}

	result := &StatusResult{
		ClusterName:       state.ClusterName,
		SessionID:         state.SessionID,
		SessionName:       state.SessionName,
		Persona:           state.Persona,
		HostMode:          string(state.HostMode),
		Owner:             state.Owner,
		LifecycleComplete: state.IsComplete(),
		Lifecycle:         state.LifecycleState(),
		ResumeAt:          state.ResumePoint(),
		Steps:             steps,
		CreatedAt:         state.CreatedAt,
		UpdatedAt:         state.UpdatedAt,
	}
	result.ResolveRuntimeStatus()
	return result
}

// ResolveRuntimeStatus turns lifecycle and live Tilt evidence into the public
// initializing/ready/failed contract reported by `cp9 status`.
func (r *StatusResult) ResolveRuntimeStatus() {
	if r == nil {
		return
	}
	r.Complete = false
	var gcp *StatusDedicatedGCPLayer
	if r.Layers != nil {
		gcp = r.Layers.DedicatedGCP
	}
	tiltReadyFailure := ""
	for _, step := range r.Steps {
		if step.Status == StatusFailed && step.Name == StepTiltReady {
			tiltReadyFailure = step.Error
			break
		}
	}
	if gcp != nil && r.Tilt != nil && r.Tilt.Status == "running" &&
		(gcp.Status == "runtime_failed" || tiltReadyFailure != "") {
		r.Status = "partial"
		r.Message = firstNonEmptyStatusText(
			tiltReadyFailure,
			gcp.Message,
			"GCP runtime is unavailable while the primary runtime remains healthy",
		)
		return
	}
	if r.Layers != nil && r.Layers.Lifecycle.Status == "failed" {
		r.Status = "failed"
		r.Message = firstNonEmptyStatusText(r.Layers.Lifecycle.Message, "infrastructure setup failed")
		return
	}
	for _, step := range r.Steps {
		if step.Status == StatusFailed {
			r.Status = "failed"
			r.Message = firstNonEmptyStatusText(step.Error, "infrastructure setup failed")
			return
		}
	}
	if gcp != nil && gcp.Status == "error" {
		r.Status = "failed"
		r.Message = firstNonEmptyStatusText(gcp.Message, "GCP regional host state is inconsistent")
		return
	}
	if !r.LifecycleComplete {
		r.Status = "initializing"
		r.Message = "infrastructure setup is still in progress"
		return
	}
	if gcp != nil && gcp.Status != "runtime_ready" {
		r.Status = "initializing"
		r.Message = firstNonEmptyStatusText(gcp.Message, "GCP runtime/controller is not configured")
		return
	}
	if gcp != nil && gcp.Tilt != nil && gcp.Tilt.TotalResources == 0 {
		r.Status = "partial"
		r.Message = "GCP runtime controller is ready; its service graph is empty"
		return
	}
	if r.Tilt == nil {
		r.Status = "ready"
		r.Message = "infrastructure and product services are ready"
		r.Complete = true
		return
	}
	if r.Tilt.Retryable && (r.Tilt.Status == "unavailable" || r.Tilt.Status == "unreachable") {
		r.Status = "initializing"
		r.Message = firstNonEmptyStatusText(r.Tilt.Message, "product service readiness is temporarily unavailable; retrying")
		return
	}
	if r.Tilt.Status == "unavailable" || r.Tilt.Status == "unreachable" ||
		r.Tilt.Status == "failed" || r.Tilt.Status == "stopped" {
		r.Status = "failed"
		r.Message = firstNonEmptyStatusText(r.Tilt.Message, "product service readiness is unavailable")
		return
	}
	if r.Tilt.Status == "running" && r.Tilt.TotalResources > 0 && r.Tilt.ReadyResources == r.Tilt.TotalResources {
		r.Status = "ready"
		r.Message = "infrastructure and product services are ready"
		r.Complete = true
		return
	}
	r.Status = "initializing"
	r.Message = fmt.Sprintf(
		"infrastructure is ready; product services are still initializing (Tilt resources ready %d/%d); run `cp9 status` again",
		r.Tilt.ReadyResources,
		r.Tilt.TotalResources,
	)
}
