"""
Paths - Centralized path resolution for configuration and environment variables.

This module provides centralized path resolution for all configurable paths in the application.
 All paths can be overridden via environment variables or config.toml.

Environment Variables:
 SLOP_CONFIG: Path to config.toml
 SLOP_LOGS_DIR: Path to logs directory
 SLOP_SCRIPTS_DIR: Path to generated scripts directory

Configuration (config.toml):
 [paths]
 logs_dir = "logs/sessions"
 scripts_dir = "scripts/generated"

Path Functions:
 get_config_path() -> Path to config.toml
 get_conductor_dir(project_path=None) -> Path to conductor directory
 get_logs_dir() -> Path to logs/sessions
 get_scripts_dir() -> Path to scripts/generated
 get_tracks_dir(project_path=None) -> Path to conductor/tracks
 get_track_state_dir(track_id, project_path=None) -> Path to conductor/tracks/<track_id>
 get_archive_dir(project_path=None) -> Path to conductor/archive

Resolution Order:
 1. Check project-specific manual_slop.toml (for conductor paths)
 2. Check environment variable (for logs/scripts)
 3. Check config.toml [paths] section (for logs/scripts)
 4. Fall back to default

Usage:
 from src.paths import get_logs_dir, get_scripts_dir

 logs_dir = get_logs_dir()
 scripts_dir = get_scripts_dir()

See Also:
 - docs/guide_tools.md for configuration documentation
 - src/session_logger.py for logging paths
 - src/project_manager.py for project paths
"""
import os
import tomllib

from pathlib import Path
from typing  import Optional, Any


_RESOLVED: dict[str, Path] = {}

def get_config_path() -> Path:
 """
 [C: tests/test_paths.py:test_default_paths]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_CONFIG", root_dir / "config.toml"))

def get_global_presets_path() -> Path:
 """
 [C: src/presets.py:PresetManager.__init__, src/presets.py:PresetManager.delete_preset, src/presets.py:PresetManager.get_preset_scope]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_GLOBAL_PRESETS", root_dir / "presets.toml"))

def get_project_presets_path(project_root: Path) -> Path:
 """
 [C: src/presets.py:PresetManager.delete_preset, src/presets.py:PresetManager.get_preset_scope, src/presets.py:PresetManager.project_path]
 """
 return project_root / "project_presets.toml"

def get_global_tool_presets_path() -> Path:
 """
 [C: src/tool_presets.py:ToolPresetManager._get_path, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_GLOBAL_TOOL_PRESETS", root_dir / "tool_presets.toml"))

def get_project_tool_presets_path(project_root: Path) -> Path:
 """
 [C: src/tool_presets.py:ToolPresetManager._get_path, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets]
 """
 return project_root / "project_tool_presets.toml"

def get_global_personas_path() -> Path:
 """
 [C: src/personas.py:PersonaManager._get_path, src/personas.py:PersonaManager.get_persona_scope, src/personas.py:PersonaManager.load_all]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_GLOBAL_PERSONAS", root_dir / "personas.toml"))

def get_project_personas_path(project_root: Path) -> Path:
 """
 [C: src/personas.py:PersonaManager._get_path, src/personas.py:PersonaManager.get_persona_scope, src/personas.py:PersonaManager.load_all]
 """
 return project_root / "project_personas.toml"

def get_global_themes_path() -> Path:
 """
 [C: src/theme_2.py:load_themes_from_disk]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_GLOBAL_THEMES", root_dir / "themes"))

def get_project_themes_path(project_root: Path) -> Path:
 """
 [C: src/theme_2.py:load_themes_from_disk]
 """
 return project_root / "project_themes.toml"

def get_global_workspace_profiles_path() -> Path:
 """
 [C: src/workspace_manager.py:WorkspaceManager._get_path, src/workspace_manager.py:WorkspaceManager.load_all_profiles]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_GLOBAL_WORKSPACE_PROFILES", root_dir / "workspace_profiles.toml"))

def get_project_workspace_profiles_path(project_root: Path) -> Path:
 """
 [C: src/workspace_manager.py:WorkspaceManager._get_path, src/workspace_manager.py:WorkspaceManager.load_all_profiles]
 """
 return project_root / ".ai" / "workspace_profiles.toml"

def get_credentials_path() -> Path:
 """
 [C: src/mcp_client.py:_is_allowed]
 """
 root_dir = Path(__file__).resolve().parent.parent
 return Path(os.environ.get("SLOP_CREDENTIALS", str(root_dir / "credentials.toml")))

def _resolve_path(env_var: str, config_key: str, default: str) -> Path:
 root_dir = Path(__file__).resolve().parent.parent
 p = None
 if env_var in os.environ:
  p = Path(os.environ[env_var])
 else:
  try:
   with open(get_config_path(), "rb") as f:
    cfg = tomllib.load(f)
   if "paths" in cfg and config_key in cfg["paths"]:
    p = Path(cfg["paths"][config_key])
  except (FileNotFoundError, tomllib.TOMLDecodeError):
   pass
 if p is None:
  p = Path(default)
 if not p.is_absolute():
  return root_dir / p
 return p

def _get_project_conductor_dir_from_toml(project_root: Path) -> Optional[Path]:
 # Look for manual_slop.toml in project_root
 toml_path = project_root / 'manual_slop.toml'
 if not toml_path.exists(): return None
 try:
  with open(toml_path, 'rb') as f:
   data = tomllib.load(f)
  # Check [conductor] dir = '...'
  c_dir = data.get('conductor', {}).get('dir')
  if c_dir:
   p = Path(c_dir)
   if not p.is_absolute(): p = project_root / p
   return p.resolve()
 except: pass
 return None

def get_conductor_dir(project_path: Optional[str] = None) -> Path:
 """
 [C: tests/test_paths.py:test_conductor_dir_project_relative, tests/test_project_paths.py:test_get_conductor_dir_default, tests/test_project_paths.py:test_get_conductor_dir_project_specific_with_toml]
 """
 if not project_path:
  # Fallback for legacy/tests, but we should avoid this
  return Path('conductor').resolve()
 
 project_root = Path(project_path).resolve()
 p            = _get_project_conductor_dir_from_toml(project_root)
 if p: return p
 return (project_root / "conductor").resolve()

def get_logs_dir() -> Path:
 """
 [C: src/session_logger.py:close_session, src/session_logger.py:open_session, tests/test_paths.py:test_config_overrides, tests/test_paths.py:test_default_paths, tests/test_paths.py:test_env_var_overrides, tests/test_paths.py:test_precedence]
 """
 if "logs_dir" not in _RESOLVED:
  _RESOLVED["logs_dir"] = _resolve_path("SLOP_LOGS_DIR", "logs_dir", "logs/sessions")
 return _RESOLVED["logs_dir"]

def get_scripts_dir() -> Path:
 """
 [C: src/session_logger.py:log_tool_call, src/session_logger.py:open_session, tests/test_paths.py:test_config_overrides, tests/test_paths.py:test_default_paths]
 """
 if "scripts_dir" not in _RESOLVED:
  _RESOLVED["scripts_dir"] = _resolve_path("SLOP_SCRIPTS_DIR", "scripts_dir", "scripts/generated")
 return _RESOLVED["scripts_dir"]

def get_tracks_dir(project_path: Optional[str] = None) -> Path:
 """
 [C: src/project_manager.py:get_all_tracks, tests/test_paths.py:test_conductor_dir_project_relative]
 """
 return get_conductor_dir(project_path) / "tracks"

def get_track_state_dir(track_id: str, project_path: Optional[str] = None) -> Path:
 """
 [C: src/project_manager.py:load_track_state, src/project_manager.py:save_track_state, tests/test_paths.py:test_conductor_dir_project_relative]
 """
 return get_tracks_dir(project_path) / track_id

def get_archive_dir(project_path: Optional[str] = None) -> Path:
 """
 [C: tests/test_paths.py:test_conductor_dir_project_relative]
 """
 return get_conductor_dir(project_path) / "archive"

def _resolve_path_info(env_var: str, config_key: str, default: str) -> dict[str, Any]:
 if env_var in os.environ:
  return {'path': Path(os.environ[env_var]).resolve(), 'source': f'env:{env_var}'}
 try:
  with open(get_config_path(), 'rb') as f:
   cfg = tomllib.load(f)
  if 'paths' in cfg and config_key in cfg['paths']:
   p = Path(cfg['paths'][config_key])
   if not p.is_absolute():
    p = (Path(__file__).resolve().parent.parent / p).resolve()
   return {'path': p, 'source': 'config.toml'}
 except: pass
 root_dir = Path(__file__).resolve().parent.parent
 p = (root_dir / default).resolve()
 return {'path': p, 'source': 'default'}

def get_full_path_info() -> dict[str, dict[str, Any]]:
 return {
  'logs_dir': _resolve_path_info('SLOP_LOGS_DIR', 'logs_dir', 'logs/sessions'),
  'scripts_dir': _resolve_path_info('SLOP_SCRIPTS_DIR', 'scripts_dir', 'scripts/generated')
 }

def reset_resolved() -> None:
 """
 For testing only - clear cached resolutions.
 [C: tests/conftest.py:reset_paths, tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_gui_phase3.py:test_conductor_setup_scan, tests/test_paths.py:reset_paths, tests/test_project_paths.py:test_get_all_tracks_project_specific, tests/test_project_paths.py:test_get_conductor_dir_default, tests/test_project_paths.py:test_get_conductor_dir_project_specific_with_toml]
 """
 _RESOLVED.clear()
 