from pathlib import Path

import shortuuid
from pydantic import BaseModel, ConfigDict

from harbor.constants import PACKAGE_CACHE_DIR, TASK_CACHE_DIR


class GitTaskId(BaseModel):
    model_config = ConfigDict(frozen=True)

    git_url: str
    git_commit_id: str | None = None
    path: Path

    def get_name(self) -> str:
        return self.path.name

    def get_local_path(self) -> Path:
        return TASK_CACHE_DIR / shortuuid.uuid(str(self)) / self.path.name


class LocalTaskId(BaseModel):
    model_config = ConfigDict(frozen=True)

    path: Path

    def get_name(self) -> str:
        return self.path.expanduser().resolve().name

    def get_local_path(self) -> Path:
        return self.path.expanduser().resolve()


class PackageTaskId(BaseModel):
    model_config = ConfigDict(frozen=True)

    org: str
    name: str
    ref: str | None = (
        None  # tag, revision, or digest (e.g. "latest", "3", "sha256:abc...")
    )

    def get_name(self) -> str:
        return self.name

    def get_local_path(self) -> Path:
        if self.ref is None or not self.ref.startswith("sha256:"):
            raise ValueError(
                "Cannot compute local path without a resolved digest. "
                "Resolve the PackageTaskId first."
            )
        digest = self.ref.removeprefix("sha256:")
        return PACKAGE_CACHE_DIR / self.org / self.name / digest
