"""run id 해석."""
from __future__ import annotations

from pathlib import Path
from typing import List

from .listing import list_runs


class ResolveError(Exception):
    """runId 해석 실패. candidates 에 후보 목록 포함."""

    def __init__(self, message: str, candidates: List[str]) -> None:
        super().__init__(message)
        self.candidates = candidates


def _all_run_ids(home: Path) -> List[str]:
    rows = list_runs(home, include_archive=True)
    return [r["runId"] for r in rows]


def resolve_run_id(home: Path, query: str) -> str:
    """prefix substring 매칭 규칙으로 runId 해석.
    1. 정확 일치 → 즉시 반환.
    2. endswith 일치 1건 → 반환.
    3. substring 일치 1건 → 반환.
    그 외(0건/다수) → ResolveError.
    """
    ids = _all_run_ids(home)
    if query in ids:
        return query
    ends = [i for i in ids if i.endswith(query)]
    if len(ends) == 1:
        return ends[0]
    if len(ends) > 1:
        raise ResolveError(f"ambiguous (endswith): {query!r}", ends)
    subs = [i for i in ids if query in i]
    if len(subs) == 1:
        return subs[0]
    if len(subs) > 1:
        raise ResolveError(f"ambiguous (substring): {query!r}", subs)
    raise ResolveError(f"no run matches {query!r}", [])


def resolve_last(home: Path, *, project: str, task_group: str) -> str:
    """가장 최근 runId 를 반환. 매칭 없으면 ResolveError."""
    rows = list_runs(home, project=project, task_group=task_group,
                     include_archive=True, limit=1)
    if not rows:
        raise ResolveError(
            f"no run found for project={project} task_group={task_group}", []
        )
    return rows[0]["runId"]
