package runtime

import "errors"

// Sentinel errors. Handlers map them to the standard JSON envelope at
// the wire boundary; lobby and admin packages observe them through
// errors.Is when they need to branch on the domain reason.
var (
	// ErrNotFound is returned when no row matches the requested
	// primary key (engine version, runtime record, player mapping).
	ErrNotFound = errors.New("runtime: not found")

	// ErrInvalidInput reports request-level validation failures
	// (empty fields, malformed semver, unknown enum values).
	ErrInvalidInput = errors.New("runtime: invalid input")

	// ErrConflict reports that the requested action conflicts with
	// the current persisted state (illegal status transition, retry
	// while a job is still in-flight, race against the reconciler).
	ErrConflict = errors.New("runtime: conflict")

	// ErrEngineVersionTaken means a duplicate primary key was
	// observed when registering a new engine version row.
	ErrEngineVersionTaken = errors.New("runtime: engine version already registered")

	// ErrEngineVersionDisabled reports that a referenced engine
	// version row exists but is marked disabled.
	ErrEngineVersionDisabled = errors.New("runtime: engine version disabled")

	// ErrPatchSemverIncompatible reports that an admin-requested
	// version patch crosses major or minor boundary, which Galaxy
	// disallows for in-place patching (per ARCHITECTURE.md §9).
	ErrPatchSemverIncompatible = errors.New("runtime: patch must stay inside the same major/minor line")

	// ErrJobQueueFull reports that the worker pool's buffered job
	// channel is at capacity. Surfaced as 503 service_unavailable at
	// the wire boundary; in practice the pool size and queue depth
	// are budgeted in `BACKEND_RUNTIME_*` env vars so the operator
	// can absorb peaks.
	ErrJobQueueFull = errors.New("runtime: job queue full")

	// ErrShutdown means the runtime service has stopped accepting
	// work because the parent context was cancelled.
	ErrShutdown = errors.New("runtime: shutting down")

	// ErrTurnAlreadyClosed reports that the runtime is currently
	// producing a turn — runtime status is `generation_in_progress`
	// — and the engine is not accepting writes for the closing
	// turn. Handlers map this to HTTP 409 with httperr code
	// `turn_already_closed`; the UI shows a conflict banner and
	// waits for the next `game.turn.ready` push.
	ErrTurnAlreadyClosed = errors.New("runtime: turn already closed")

	// ErrGamePaused reports that the game is not in a state that
	// accepts user-games commands or orders: the runtime row
	// carries `paused = true`, or the runtime status lands on any
	// terminal value (`engine_unreachable`, `generation_failed`,
	// `stopped`, `finished`, `removed`), or the game has not yet
	// finished bootstrapping (`starting`). Handlers map this to
	// HTTP 409 with httperr code `game_paused`; the UI surfaces a
	// pause banner and waits for an admin resume or a fresh
	// snapshot.
	ErrGamePaused = errors.New("runtime: game paused")
)
