package runtime

import (
	"time"

	"github.com/google/uuid"
)

// EngineVersion mirrors a row in `backend.engine_versions`. The version
// label is the primary key and is also the value lobby stores on
// `games.target_engine_version`.
type EngineVersion struct {
	Version   string
	ImageRef  string
	Enabled   bool
	CreatedAt time.Time
	UpdatedAt time.Time
}

// RuntimeRecord mirrors a row in `backend.runtime_records`. Pointer
// fields are nullable in the schema; primitives default to zero.
type RuntimeRecord struct {
	GameID               uuid.UUID
	Status               string
	CurrentContainerID   string
	CurrentImageRef      string
	CurrentEngineVersion string
	EngineEndpoint       string
	StatePath            string
	DockerNetwork        string
	TurnSchedule         string
	CurrentTurn          int32
	NextGenerationAt     *time.Time
	SkipNextTick         bool
	Paused               bool
	PausedAt             *time.Time
	EngineHealth         string
	CreatedAt            time.Time
	UpdatedAt            time.Time
	StartedAt            *time.Time
	StoppedAt            *time.Time
	FinishedAt           *time.Time
	RemovedAt            *time.Time
	LastObservedAt       *time.Time
}

// IsTerminal reports whether the record sits in a status that the
// cache should evict.
func (r RuntimeRecord) IsTerminal() bool {
	switch r.Status {
	case RuntimeStatusFinished, RuntimeStatusRemoved, RuntimeStatusStopped:
		return true
	default:
		return false
	}
}

// PlayerMapping mirrors a row in `backend.player_mappings`. The
// composite primary key is `(game_id, user_id)`; `engine_player_uuid`
// is the engine-assigned race id used by the engine's `actor` field.
type PlayerMapping struct {
	GameID           uuid.UUID
	UserID           uuid.UUID
	RaceName         string
	EnginePlayerUUID uuid.UUID
	CreatedAt        time.Time
}

// OperationLog mirrors a row in `backend.runtime_operation_log`. Used
// by admin endpoints that surface a per-operation status envelope and
// by the worker pool for completion telemetry.
type OperationLog struct {
	OperationID  uuid.UUID
	GameID       uuid.UUID
	Op           string
	Source       string
	Status       string
	ImageRef     string
	ContainerID  string
	ErrorCode    string
	ErrorMessage string
	StartedAt    time.Time
	FinishedAt   *time.Time
}

// HealthSnapshot mirrors a row in `backend.runtime_health_snapshots`.
// The `Payload` field carries the JSON-encoded engine status response
// or a synthesised summary when the engine is unreachable.
type HealthSnapshot struct {
	SnapshotID uuid.UUID
	GameID     uuid.UUID
	ObservedAt time.Time
	Payload    []byte
}

// Game is the read-only projection of a `backend.games` row that the
// runtime needs at start time. It is the runtime's view of a lobby
// row; lobby remains the only writer.
type Game struct {
	GameID              uuid.UUID
	OwnerUserID         *uuid.UUID
	Visibility          string
	Status              string
	GameName            string
	TurnSchedule        string
	TargetEngineVersion string
	MinPlayers          int32
	MaxPlayers          int32
	StartGapHours       int32
	StartGapPlayers     int32
}

// MembershipRow is the read-only projection of an active
// `backend.memberships` row that the runtime needs at start time. It
// carries enough data to populate the engine `Init` request and the
// `player_mappings` projection.
type MembershipRow struct {
	MembershipID uuid.UUID
	GameID       uuid.UUID
	UserID       uuid.UUID
	RaceName     string
}
