"""State directory path utilities."""

from __future__ import annotations

from pathlib import Path

from .git_repository import get_git_common_directory_path, get_git_directory_path


def get_state_directory_path() -> Path:
    """Get the path to the state directory for session data.

    Returns:
        Path to .git/git-stage-batch/ directory
    """
    return get_git_directory_path() / "git-stage-batch"


def get_session_lock_file_path() -> Path:
    """Get the path to the repository-wide session lock file.

    Returns:
        Path to session lock file
    """
    return get_common_state_directory_path() / "session.lock"


def get_common_state_directory_path() -> Path:
    """Get the state directory shared by every linked worktree."""
    return get_git_common_directory_path() / "git-stage-batch"


def get_active_session_owner_file_path() -> Path:
    """Get the repository-wide active-session ownership record path."""
    return get_common_state_directory_path() / "active-session.json"


def ensure_common_state_directory_exists() -> None:
    """Create the repository-wide state directory if it does not exist."""
    get_common_state_directory_path().mkdir(parents=True, exist_ok=True)


def ensure_state_directory_exists() -> None:
    """Create the state directory if it doesn't exist."""
    get_state_directory_path().mkdir(parents=True, exist_ok=True)


def get_session_directory_path() -> Path:
    """Get the directory containing active session scratch state."""
    return get_state_directory_path() / "session"


def get_selected_state_directory_path() -> Path:
    """Get the directory containing the selected change cache."""
    return get_session_directory_path() / "selected"


def get_progress_state_directory_path() -> Path:
    """Get the directory containing hunk progress state."""
    return get_session_directory_path() / "progress"


def get_processed_state_directory_path() -> Path:
    """Get the directory containing processed line-id state."""
    return get_session_directory_path() / "processed"


def get_config_state_directory_path() -> Path:
    """Get the directory containing session configuration state."""
    return get_session_directory_path() / "config"


def get_auto_advance_config_file_path() -> Path:
    """Get the path to the automatic hunk selection preference."""
    return get_config_state_directory_path() / "auto-advance.txt"


def get_abort_state_directory_path() -> Path:
    """Get the directory containing abort/recovery state."""
    return get_session_directory_path() / "abort"


def get_fixup_state_directory_path() -> Path:
    """Get the directory containing suggest-fixup state."""
    return get_session_directory_path() / "fixup"


def get_rewrite_state_directory_path() -> Path:
    """Get the directory containing durable rewrite operation state."""
    return get_common_state_directory_path() / "rewrite"


def get_candidate_state_directory_path() -> Path:
    """Get the directory containing batch candidate iteration state."""
    return get_session_directory_path() / "candidates"


def get_batch_candidate_state_file_path() -> Path:
    """Get the path to the batch candidate state file."""
    return get_candidate_state_directory_path() / "state.json"


def get_processed_include_ids_file_path() -> Path:
    """Get the path to the processed include IDs file.

    Returns:
        Path to processed include IDs file
    """
    return get_processed_state_directory_path() / "included-lines.json"


def get_processed_skip_ids_file_path() -> Path:
    """Get the path to the processed skip IDs file.

    Returns:
        Path to processed skip IDs file
    """
    return get_processed_state_directory_path() / "skipped-lines.json"


def get_line_changes_json_file_path() -> Path:
    """Get the path to the selected lines JSON file.

    Returns:
        Path to selected lines JSON file
    """
    return get_selected_state_directory_path() / "hunk.lines.json"


def get_index_snapshot_file_path() -> Path:
    """Get the path to the index snapshot file.

    Returns:
        Path to index snapshot file
    """
    return get_selected_state_directory_path() / "index.snapshot"


def get_working_tree_snapshot_file_path() -> Path:
    """Get the path to the working tree snapshot file.

    Returns:
        Path to working tree snapshot file
    """
    return get_selected_state_directory_path() / "working-tree.snapshot"


def get_snapshot_metadata_file_path() -> Path:
    """Get the selected-file snapshot metadata manifest path."""
    return get_selected_state_directory_path() / "snapshots.json"


def get_block_list_file_path() -> Path:
    """Get the path to the blocklist file for tracking processed hunks.

    Returns:
        Path to blocklist file
    """
    return get_progress_state_directory_path() / "blocked-hunks.txt"


def get_selected_hunk_patch_file_path() -> Path:
    """Get the path to the selected hunk patch file.

    Returns:
        Path to selected hunk patch file
    """
    return get_selected_state_directory_path() / "hunk.patch"


def get_selected_hunk_hash_file_path() -> Path:
    """Get the path to the selected hunk hash file.

    Returns:
        Path to selected hunk hash file
    """
    return get_selected_state_directory_path() / "hunk.hash.txt"


def get_selected_change_kind_file_path() -> Path:
    """Get the path to the selected change kind marker file."""
    return get_selected_state_directory_path() / "change-kind.txt"


def get_selected_change_clear_reason_file_path() -> Path:
    """Get the path to the marker explaining an intentionally cleared selection."""
    return get_selected_state_directory_path() / "clear-reason.txt"


def get_last_file_review_state_file_path() -> Path:
    """Get the path to the most recent file-review safety state."""
    return get_selected_state_directory_path() / "file-review.json"


def get_selected_binary_file_json_path() -> Path:
    """Get the path to the selected binary file JSON file.

    When the selected item is a binary file (not a text hunk), this file stores
    the BinaryFileChange information as JSON.

    Returns:
        Path to selected binary file JSON file
    """
    return get_selected_state_directory_path() / "binary-file.json"


def get_selected_gitlink_file_json_path() -> Path:
    """Get the path to the selected gitlink JSON file."""
    return get_selected_state_directory_path() / "gitlink-file.json"


def get_selected_mode_change_json_path() -> Path:
    """Get the path to the selected executable-mode change JSON file."""
    return get_selected_state_directory_path() / "mode-change.json"


def get_selected_rename_file_json_path() -> Path:
    """Get the path to the selected rename JSON file."""
    return get_selected_state_directory_path() / "rename-file.json"


def get_selected_text_deletion_file_json_path() -> Path:
    """Get the path to the selected text deletion JSON file."""
    return get_selected_state_directory_path() / "text-deletion-file.json"


def get_abort_head_file_path() -> Path:
    """Get the path to the abort HEAD file for session restoration.

    Returns:
        Path to abort HEAD file
    """
    return get_abort_state_directory_path() / "head.txt"


def get_abort_stash_file_path() -> Path:
    """Get the path to the abort stash file for session restoration.

    Returns:
        Path to abort stash file
    """
    return get_abort_state_directory_path() / "stash.txt"


def get_abort_snapshots_directory_path() -> Path:
    """Get the path to the abort snapshots directory.

    Returns:
        Path to snapshots directory
    """
    return get_abort_state_directory_path() / "untracked"


def ensure_abort_snapshots_directory_exists() -> None:
    """Create the untracked-file recovery directory if it does not exist."""
    get_abort_snapshots_directory_path().mkdir(parents=True, exist_ok=True)


def get_abort_snapshot_list_file_path() -> Path:
    """Get the path to the abort snapshot list file.

    Returns:
        Path to snapshot list file
    """
    return get_abort_state_directory_path() / "untracked-paths.txt"


def get_abort_intent_to_add_entries_file_path() -> Path:
    """Get the path to exact pre-session intent-to-add index metadata."""
    return get_abort_state_directory_path() / "intent-to-add-entries.json"


def get_abort_applied_batch_overlays_file_path() -> Path:
    """Get the abort snapshot of durable applied-batch overlay state."""
    return get_abort_state_directory_path() / "applied-batch-overlays.json"


def get_abort_applied_batch_overlays_absent_file_path() -> Path:
    """Get the marker recording absent applied-batch state at session start."""
    return get_abort_state_directory_path() / "applied-batch-overlays.absent"


def get_abort_applied_batch_overlay_fresh_index_file_path() -> Path:
    """Get the session-start list of overlays with a fresh index identity."""
    return get_abort_state_directory_path() / "applied-batch-overlays-index.json"


def get_staged_renames_file_path() -> Path:
    """Get the path to start-time staged rename metadata."""
    return get_abort_state_directory_path() / "staged-renames.json"


def get_staged_deletions_file_path() -> Path:
    """Get the path to start-time staged text deletion metadata."""
    return get_abort_state_directory_path() / "staged-deletions.json"


def get_session_batch_sources_file_path() -> Path:
    """Get the path to the session batch sources cache file.

    Returns:
        Path to session-batch-sources.json file
    """
    return get_session_directory_path() / "batch-sources.json"


def get_session_consumed_selections_file_path() -> Path:
    """Get the path to the hidden consumed-selection ownership cache.

    Returns:
        Path to session-consumed-selections.json file
    """
    return get_session_directory_path() / "consumed-selections.json"


def get_auto_added_files_file_path() -> Path:
    """Get the path to the auto-added files list file.

    Returns:
        Path to auto-added files list file
    """
    return get_abort_state_directory_path() / "auto-added-files.txt"


def get_blocked_files_file_path() -> Path:
    """Get the path to the blocked files list file.

    Returns:
        Path to blocked files list file
    """
    return get_progress_state_directory_path() / "blocked-files.txt"


def get_iteration_count_file_path() -> Path:
    """Get the path to the iteration count file.

    Returns:
        Path to iteration count file
    """
    return get_config_state_directory_path() / "iteration-count.txt"


def get_start_head_file_path() -> Path:
    """Get the path to file storing HEAD SHA at session start.

    Returns:
        Path to start HEAD file
    """
    return get_session_directory_path() / "start-head.txt"


def get_start_index_tree_file_path() -> Path:
    """Get the path to file storing index tree SHA at session start.

    Returns:
        Path to start index tree file
    """
    return get_session_directory_path() / "start-index-tree.txt"


def get_context_lines_file_path() -> Path:
    """Get the path to the context lines configuration file.

    Returns:
        Path to context lines file
    """
    return get_config_state_directory_path() / "context-lines.txt"


def get_suggest_fixup_state_file_path() -> Path:
    """Get the path to the suggest-fixup state file.

    Returns:
        Path to suggest-fixup state JSON file
    """
    return get_fixup_state_directory_path() / "state.json"


def get_included_hunks_file_path() -> Path:
    """Get the path to the included hunks file.

    Returns:
        Path to included hunks file
    """
    return get_progress_state_directory_path() / "included-hunks.txt"


def get_skipped_hunks_jsonl_file_path() -> Path:
    """Get the path to the skipped hunks JSONL file.

    Returns:
        Path to skipped hunks JSONL file
    """
    return get_progress_state_directory_path() / "skipped-hunks.jsonl"


def get_discarded_hunks_file_path() -> Path:
    """Get the path to the discarded hunks file.

    Returns:
        Path to discarded hunks file
    """
    return get_progress_state_directory_path() / "discarded-hunks.txt"


def get_batches_directory_path() -> Path:
    """Get the directory containing batch metadata.

    Returns:
        Path to batches directory
    """
    return get_state_directory_path() / "batches"


def get_applied_batch_overlays_file_path() -> Path:
    """Get durable worktree-local provenance for explicit batch applications."""
    return get_state_directory_path() / "applied-batch-overlays.json"


def get_session_applied_batch_overlay_paths_file_path() -> Path:
    """Get paths whose applied overlays were written in this session."""
    return get_session_directory_path() / "applied-batch-overlay-paths.txt"


def get_batch_directory_path(batch_name: str) -> Path:
    """Get the directory for a specific batch's metadata.

    Args:
        batch_name: Name of the batch

    Returns:
        Path to batch directory
    """
    return get_batches_directory_path() / batch_name


def get_batch_metadata_file_path(batch_name: str) -> Path:
    """Get the metadata file path for a specific batch.

    Args:
        batch_name: Name of the batch

    Returns:
        Path to batch metadata JSON file
    """
    return get_batch_directory_path(batch_name) / "metadata.json"


def get_batch_refs_snapshot_file_path() -> Path:
    """Get the batch refs snapshot file path (for abort functionality).

    Returns:
        Path to batch refs snapshot JSON file
    """
    return get_abort_state_directory_path() / "batch-refs.json"


def get_abort_recovery_anchors_file_path() -> Path:
    """Get the path recording abort recovery anchor refs and object IDs."""
    return get_abort_state_directory_path() / "recovery-anchors.json"


def get_session_start_point_file_path() -> Path:
    """Get the persisted commit-backed or unborn session start point."""
    return get_abort_state_directory_path() / "start-point.json"
