from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Any, Protocol

from one_run.models import Manifest, RunMetadata, RunStatus
from one_run.run_dir import RunPaths


@dataclass(frozen=True)
class RunContext:
    run_id: str
    manifest_path: Path
    manifest: Manifest
    paths: RunPaths
    project_root: Path
    metadata: RunMetadata


@dataclass(frozen=True)
class BackendStartResult:
    state: str
    started_at: datetime | None = None
    ended_at: datetime | None = None
    exit_code: int | None = None
    message: str | None = None
    slurm_job_id: str | None = None
    docker_image_digest: str | None = None
    runtime: dict[str, Any] | None = None


@dataclass(frozen=True)
class BackendQueryResult:
    state: str
    exit_code: int | None = None
    message: str | None = None
    runtime: dict[str, Any] | None = None


class Backend(Protocol):
    def prepare(self, run_ctx: RunContext) -> None:
        ...

    def start(self, run_ctx: RunContext) -> BackendStartResult:
        ...

    def query(self, run_ctx: RunContext, status: RunStatus) -> BackendQueryResult | None:
        ...

    def cancel(self, run_ctx: RunContext) -> None:
        ...
