from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum
from pathlib import Path


class RuntimeMode(StrEnum):
    CUDA = "cuda"
    AUTO = "auto"
    CPU = "cpu"

    @property
    def requires_cuda(self) -> bool:
        return self is RuntimeMode.CUDA

    @property
    def allows_cpu_fallback(self) -> bool:
        return self is RuntimeMode.AUTO


class FormulaParser(StrEnum):
    NOUGAT = "nougat"
    MARKER = "marker"


@dataclass(frozen=True)
class ConversionOptions:
    runtime: RuntimeMode | str = RuntimeMode.CUDA
    formula_parser: FormulaParser | str = FormulaParser.NOUGAT
    chunk_target_pages: int = 20
    output_dir: Path | str = Path("output")
    nougat_command: Path | str | None = None
    model_cache_dir: Path | str | None = None
    log_dir: Path | str | None = None
    resume: bool = False
    write_logs: bool = True

    def __post_init__(self) -> None:
        object.__setattr__(self, "runtime", RuntimeMode(self.runtime))
        object.__setattr__(self, "formula_parser", FormulaParser(self.formula_parser))
        object.__setattr__(self, "output_dir", Path(self.output_dir))
        object.__setattr__(
            self,
            "nougat_command",
            None if self.nougat_command is None else Path(self.nougat_command),
        )
        object.__setattr__(
            self,
            "model_cache_dir",
            None if self.model_cache_dir is None else Path(self.model_cache_dir),
        )
        object.__setattr__(
            self,
            "log_dir",
            None if self.log_dir is None else Path(self.log_dir),
        )
        if self.chunk_target_pages < 1:
            raise ValueError("chunk_target_pages must be >= 1")

    @property
    def requires_cuda(self) -> bool:
        return self.runtime.requires_cuda

    @property
    def allows_cpu_fallback(self) -> bool:
        return self.runtime.allows_cpu_fallback
