"""Project discovery and context resolution for brokr."""

from pathlib import Path
from typing import Dict, Optional, Tuple

PROJECT_FILE_NAME = ".brokr"
MAX_WALK_DEPTH = 10
MAX_PROJECT_NAME_LEN = 128


def find_project_file(start_dir: Optional[Path] = None) -> Optional[Path]:
    """Walk up from start_dir to find a .brokr file."""
    if start_dir is None:
        start_dir = Path.cwd()

    current = start_dir.resolve()
    for _ in range(MAX_WALK_DEPTH):
        candidate = current / PROJECT_FILE_NAME
        if candidate.is_file():
            return candidate
        parent = current.parent
        if parent == current:
            break
        current = parent
    return None


def read_project_name(project_file: Path) -> str:
    """Read project name from a .brokr file (first line, stripped)."""
    text = project_file.read_text().strip()
    if not text:
        raise ValueError(f"Empty .brokr file at {project_file}")
    name = text.splitlines()[0].strip()
    if len(name) > MAX_PROJECT_NAME_LEN:
        raise ValueError(
            f"Project name too long (max {MAX_PROJECT_NAME_LEN} chars)"
        )
    return name


def resolve_project(store_data: dict, start_dir: Optional[Path] = None) -> Tuple[str, dict]:
    """Find current project context from cwd.

    Returns (project_name, project_data) or raises BrokrError.
    """
    from brokr.store import BrokrError

    project_file = find_project_file(start_dir)
    if project_file is None:
        raise BrokrError(
            "No project context. No .brokr file found in current or parent directories."
        )

    project_name = read_project_name(project_file)
    projects = store_data.get("projects", {})

    if project_name not in projects:
        raise BrokrError(
            f"Project '{project_name}' not found in store. "
            f"Run `brokr project init {project_name}`."
        )

    return project_name, projects[project_name]


def get_project_secrets(store_data: dict, project_name: str) -> Dict[str, str]:
    """Resolve project secret names to {name: value} dict.

    Skips secrets that exist in project list but were deleted from store.
    """
    all_secrets = store_data.get("secrets", {})
    projects = store_data.get("projects", {})
    project = projects.get(project_name, {})
    project_secret_names = project.get("secrets", [])

    return {k: all_secrets[k] for k in project_secret_names if k in all_secrets}


def get_agent_secrets(
    store_data: dict, project_name: str, agent_name: str
) -> Dict[str, str]:
    """Resolve agent grant names to {name: value} dict.

    Raises BrokrError if agent doesn't exist in the project.
    Skips granted secrets that were deleted from store.
    """
    from brokr.store import BrokrError

    all_secrets = store_data.get("secrets", {})
    projects = store_data.get("projects", {})
    project = projects.get(project_name, {})
    agents = project.get("agents", {})

    if agent_name not in agents:
        raise BrokrError(
            f"Agent '{agent_name}' not found in project '{project_name}'."
        )

    agent_secret_names = agents[agent_name]
    return {k: all_secrets[k] for k in agent_secret_names if k in all_secrets}
