from __future__ import annotations

import socket
from datetime import datetime
from pathlib import Path

from one_run.models import Manifest, RunMetadata
from one_run.utils.shell import run_capture


def _git_commit(project_root: Path) -> str | None:
    proc = run_capture(["git", "rev-parse", "HEAD"], cwd=project_root)
    if proc.returncode != 0:
        return None
    commit = proc.stdout.strip()
    return commit or None


def _git_dirty(project_root: Path) -> bool | None:
    proc = run_capture(["git", "status", "--porcelain"], cwd=project_root)
    if proc.returncode != 0:
        return None
    return bool(proc.stdout.strip())


def build_metadata(
    run_id: str,
    manifest: Manifest,
    project_root: Path,
    cwd: Path,
    *,
    slurm_job_id: str | None = None,
) -> RunMetadata:
    return RunMetadata(
        run_id=run_id,
        timestamp=datetime.now(),
        hostname=socket.gethostname(),
        cwd=str(cwd),
        project_root=str(project_root),
        git_commit=_git_commit(project_root),
        git_dirty=_git_dirty(project_root),
        experiment_name=manifest.experiment.name,
        tags=manifest.experiment.tags,
        experiment_color=manifest.experiment.color,
        backend_type=manifest.backend.kind,
        docker_image=manifest.environment.image if manifest.environment.kind == "docker" else None,
        docker_image_digest=None,
        slurm_job_id=slurm_job_id,
        slurm_attempt=1 if manifest.backend.kind == "slurm" else None,
    )
