"""Configuration management for the SQ API."""

import os
from typing import Optional

from .exceptions import SQAPIConfigError
from .constants import LIB_NAME


class SQAPIConfig:
    """Configuration for SQ API.
    
    Attributes:
        lib_dir: Library directory path containing phase database files.
        dll_path: Path to the SQ API DLL file.
    """
    
    __slots__ = ('lib_dir', 'dll_path')
    
    DEFAULT_LIB_DIR = r"C:\Program Files\Siroquant\V5\Database"
    
    def __init__(
        self,
        lib_dir: Optional[str] = None,
        dll_path: Optional[str] = None,
        validate: bool = True
    ) -> None:
        """Initialize configuration from environment or parameters.
        
        Args:
            lib_dir: Library directory path (relative or absolute).
            dll_path: DLL path (relative or absolute).
            validate: If True, validate that dll_path exists on init.
        
        Raises:
            SQAPIConfigError: If validate=True and dll_path doesn't exist.
        """
        # Get the directory path, convert relative to absolute
        lib_dir_raw = lib_dir or os.getenv('SQ_LIB_DIR', self.DEFAULT_LIB_DIR)
        self.lib_dir = os.path.abspath(lib_dir_raw) if lib_dir_raw else self.DEFAULT_LIB_DIR
        
        # Get the DLL path, convert relative to absolute if provided
        dll_path_raw = dll_path or os.getenv('SQ_DLL_PATH')
        self.dll_path = os.path.abspath(dll_path_raw) if dll_path_raw else None
        
        # Validate early if requested
        if validate and self.dll_path and not os.path.exists(self.dll_path):
            raise SQAPIConfigError(
                f"DLL not found at configured path: {self.dll_path}",
                error_code=None
            )
    
    def find_dll(self, package_dir: Optional[str] = None) -> str:
        """Find the DLL file.
        
        If dll_path is explicitly configured, it must exist.
        Otherwise, searches in package directory and system path.
        
        Args:
            package_dir: Package directory to search for DLL.
        
        Returns:
            Path to the DLL file.
        
        Raises:
            FileNotFoundError: If configured DLL path doesn't exist.
        """
        # If explicit path provided, it must exist
        if self.dll_path:
            if os.path.exists(self.dll_path):
                return self.dll_path
            raise FileNotFoundError(
                f"Configured DLL path not found: {self.dll_path}"
            )
        
        # Search in package directory
        if package_dir:
            dll_path = os.path.join(package_dir, LIB_NAME)
            if os.path.exists(dll_path):
                return dll_path
        
        # Check if it exists in current directory
        dll_path = os.path.abspath(LIB_NAME)
        if os.path.exists(dll_path):
            return dll_path
        
        # Fallback to just the name (let OS find it in PATH)
        return LIB_NAME
    
    def get_lib_dir(self) -> str:
        """Get library directory."""
        return self.lib_dir or self.DEFAULT_LIB_DIR
    
    def __repr__(self) -> str:
        return f"SQAPIConfig(lib_dir={self.lib_dir!r}, dll_path={self.dll_path!r})"
