from __future__ import annotations

from dataclasses import dataclass
from typing import Any, TypeAlias

from . import compiler
from .types import ExistingPod


@dataclass
class PodOpBase:
    def op(self) -> tuple[compiler.CompiledPod | None, ExistingPod | None]:
        return None, None


@dataclass
class Superceded(PodOpBase):
    pod: compiler.CompiledDeletePod
    by: compiler.CompiledPod

    def __str__(self):
        return f"[Superceded] {self.by.pod_id} ({self.by.get_name()})"


@dataclass
class Absent(PodOpBase):
    pod: compiler.CompiledDeletePod

    def __str__(self):
        return f"[Absent]     {self.pod.pod_id}"


@dataclass
class Delete(PodOpBase):
    pod: compiler.CompiledDeletePod
    existing: ExistingPod

    def op(self) -> tuple[None, ExistingPod]:
        return None, self.existing

    def __str__(self):
        return f"[Delete]     {self.pod.pod_id} ({self.existing.current_name})"


@dataclass
class Rebuild(PodOpBase):
    pod: compiler.CompiledPod
    existing: ExistingPod
    conflicts: list[tuple[str, Any, Any]]

    def op(self) -> tuple[compiler.CompiledPod, ExistingPod]:
        return self.pod, self.existing

    def __str__(self):
        lines = [f"[Rebuild]    {self.pod.pod_id} ({self.pod.get_name()})"]
        for kind, after, before in self.conflicts:
            lines.append(f"  {kind} = {before} -> {after}")
        return "\n".join(lines)


@dataclass
class Present(PodOpBase):
    pod: compiler.CompiledPod
    existing: ExistingPod

    def op(self) -> tuple[None, None]:
        return None, None

    def __str__(self):
        return f"[Present]    {self.pod.pod_id} ({self.pod.get_name()})"


@dataclass
class Create(PodOpBase):
    pod: compiler.CompiledPod

    def op(self) -> tuple[compiler.CompiledPod, None]:
        return self.pod, None

    def __str__(self):
        return f"[Create] {self.pod.pod_id} ({self.pod.get_name()})"


PodOp: TypeAlias = Superceded | Absent | Delete | Rebuild | Present | Create
