"""Exceptions for Copy-on-Write filesystem operations."""

from __future__ import annotations


class CoWError(Exception):
    """Base exception for CoW operations."""

    def __init__(self, message: str) -> None:
        self.message = message
        super().__init__(message)


class PoolNotFoundError(CoWError):
    """Pool does not exist."""

    def __init__(self, name: str) -> None:
        self.pool_name = name
        super().__init__(f"Pool not found: {name}")


class PoolExistsError(CoWError):
    """Pool already exists."""

    def __init__(self, name: str) -> None:
        self.pool_name = name
        super().__init__(f"Pool already exists: {name}")


class PoolNotEmptyError(CoWError):
    """Pool has datasets and cannot be destroyed."""

    def __init__(self, name: str, dataset_count: int) -> None:
        self.pool_name = name
        self.dataset_count = dataset_count
        super().__init__(
            f"Pool '{name}' has {dataset_count} datasets. Use --force to destroy."
        )


class DatasetNotFoundError(CoWError):
    """Dataset does not exist."""

    def __init__(self, pool: str, name: str) -> None:
        self.pool = pool
        self.dataset_name = name
        super().__init__(f"Dataset not found: {pool}/{name}")


class DatasetExistsError(CoWError):
    """Dataset already exists."""

    def __init__(self, pool: str, name: str) -> None:
        self.pool = pool
        self.dataset_name = name
        super().__init__(f"Dataset already exists: {pool}/{name}")


class DatasetNotEmptyError(CoWError):
    """Dataset has snapshots and cannot be destroyed."""

    def __init__(self, pool: str, name: str, snapshot_count: int) -> None:
        self.pool = pool
        self.dataset_name = name
        self.snapshot_count = snapshot_count
        super().__init__(
            f"Dataset '{pool}/{name}' has {snapshot_count} snapshots. Use --force to destroy."
        )


class SnapshotNotFoundError(CoWError):
    """Snapshot does not exist."""

    def __init__(self, pool: str, dataset: str, name: str) -> None:
        self.pool = pool
        self.dataset = dataset
        self.snapshot_name = name
        super().__init__(f"Snapshot not found: {pool}/{dataset}@{name}")


class SnapshotExistsError(CoWError):
    """Snapshot already exists."""

    def __init__(self, pool: str, dataset: str, name: str) -> None:
        self.pool = pool
        self.dataset = dataset
        self.snapshot_name = name
        super().__init__(f"Snapshot already exists: {pool}/{dataset}@{name}")


class SnapshotHasClonesError(CoWError):
    """Snapshot has clones and cannot be deleted."""

    def __init__(self, pool: str, dataset: str, name: str) -> None:
        self.pool = pool
        self.dataset = dataset
        self.snapshot_name = name
        super().__init__(
            f"Snapshot '{pool}/{dataset}@{name}' has dependent clones. "
            "Promote or destroy clones first."
        )


class CloneNotFoundError(CoWError):
    """Clone does not exist."""

    def __init__(self, pool: str, name: str) -> None:
        self.pool = pool
        self.clone_name = name
        super().__init__(f"Clone not found: {pool}/{name}")


class BackendNotAvailableError(CoWError):
    """CoW backend is not available on this system."""

    def __init__(self, backend: str, reason: str | None = None) -> None:
        self.backend = backend
        self.reason = reason
        msg = f"Backend '{backend}' is not available"
        if reason:
            msg += f": {reason}"
        super().__init__(msg)


class InvalidMountPointError(CoWError):
    """Mount point is not a valid CoW filesystem."""

    def __init__(self, path: str, expected_type: str) -> None:
        self.path = path
        self.expected_type = expected_type
        super().__init__(
            f"Path '{path}' is not a valid {expected_type} filesystem mount point"
        )


class InsufficientPermissionsError(CoWError):
    """Operation requires elevated permissions."""

    def __init__(self, operation: str) -> None:
        self.operation = operation
        super().__init__(f"Operation '{operation}' requires root privileges")


class SendReceiveError(CoWError):
    """Error during send/receive operation."""

    def __init__(self, operation: str, reason: str) -> None:
        self.operation = operation
        self.reason = reason
        super().__init__(f"Send/receive {operation} failed: {reason}")


class QuotaError(CoWError):
    """Quota-related error."""

    def __init__(self, message: str) -> None:
        super().__init__(message)
