"""Obsidian domain policies."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Protocol

from .entities import Note, Vault
from .exceptions import InvalidNoteError, InvalidVaultError
from .value_objects import NotePath


class VaultPolicy(Protocol):
    def can_add_note(self, vault: Vault, note: Note) -> bool: ...
    def can_move_note(self, vault: Vault, note: Note, new_path: NotePath) -> bool: ...
    def can_restore_note(self, note: Note) -> bool: ...


@dataclass(frozen=True)
class DefaultVaultPolicy:
    def can_add_note(self, vault: Vault, note: Note) -> bool:
        if not isinstance(vault, Vault):
            raise TypeError("vault must be a Vault instance")
        if not isinstance(note, Note):
            raise TypeError("note must be a Note instance")
        return note.path.value not in {existing.path.value for existing in vault.notes}

    def can_move_note(self, vault: Vault, note: Note, new_path: NotePath) -> bool:
        if not isinstance(vault, Vault):
            raise TypeError("vault must be a Vault instance")
        if not isinstance(note, Note):
            raise TypeError("note must be a Note instance")
        if not isinstance(new_path, NotePath):
            raise TypeError("new_path must be a NotePath instance")
        if note.path == new_path:
            return True
        return new_path.value not in {existing.path.value for existing in vault.notes}

    def can_restore_note(self, note: Note) -> bool:
        if not isinstance(note, Note):
            raise TypeError("note must be a Note instance")
        return True
