"""Tech stack detection using file heuristics."""

import os
from pathlib import Path
from typing import Optional
from enum import Enum


class TechStack(Enum):
    """Supported tech stacks."""
    LARAVEL = "laravel"
    PHOENIX = "phoenix"
    PYTHON = "python"
    UNKNOWN = "unknown"


class StackDetector:
    """Detects tech stack of a project using file heuristics."""
    
    def __init__(self, project_path: Path):
        """Initialize detector with project path."""
        self.project_path = Path(project_path)
    
    def detect_stack(self) -> TechStack:
        """Detect the tech stack of the project.
        
        Returns:
            Detected tech stack
        """
        # Check for Laravel
        if self._is_laravel():
            return TechStack.LARAVEL
        
        # Check for Phoenix
        if self._is_phoenix():
            return TechStack.PHOENIX
        
        # Check for Python
        if self._is_python():
            return TechStack.PYTHON
        
        return TechStack.UNKNOWN
    
    def _is_laravel(self) -> bool:
        """Check if project is a Laravel application."""
        laravel_indicators = [
            "composer.json",
            "artisan",
            "app/Http/Kernel.php",
            "config/app.php"
        ]
        
        # Check for composer.json with Laravel dependencies
        composer_json = self.project_path / "composer.json"
        if composer_json.exists():
            try:
                import json
                with open(composer_json, 'r') as f:
                    composer_data = json.load(f)
                    
                # Check for Laravel in dependencies
                dependencies = composer_data.get('require', {})
                if 'laravel/framework' in dependencies:
                    return True
            except:
                pass
        
        # Check for Laravel-specific files
        laravel_files = [
            self.project_path / "artisan",
            self.project_path / "app",
            self.project_path / "config" / "app.php"
        ]
        
        return any(path.exists() for path in laravel_files)
    
    def _is_phoenix(self) -> bool:
        """Check if project is a Phoenix application."""
        phoenix_indicators = [
            "mix.exs",
            "config/config.exs",
            "lib",
            "assets"
        ]
        
        # Check for mix.exs with Phoenix dependencies
        mix_exs = self.project_path / "mix.exs"
        if mix_exs.exists():
            try:
                with open(mix_exs, 'r') as f:
                    content = f.read()
                    if 'phoenix' in content.lower():
                        return True
            except:
                pass
        
        # Check for Phoenix-specific files
        phoenix_files = [
            self.project_path / "mix.exs",
            self.project_path / "config" / "config.exs",
            self.project_path / "lib"
        ]
        
        return any(path.exists() for path in phoenix_files)
    
    def _is_python(self) -> bool:
        """Check if project is a Python application."""
        # Check for Python-specific files
        python_files = [
            self.project_path / "requirements.txt",
            self.project_path / "setup.py",
            self.project_path / "pyproject.toml",
            self.project_path / "Pipfile",
            self.project_path / "environment.yml"
        ]
        
        if any(path.exists() for path in python_files):
            return True
        
        # Check for .py files in root or common Python directories
        python_dirs = [
            self.project_path,
            self.project_path / "src",
            self.project_path / "app",
            self.project_path / "lib"
        ]
        
        for directory in python_dirs:
            if directory.exists() and directory.is_dir():
                py_files = list(directory.glob("*.py"))
                if py_files:
                    return True
        
        return False
    
    def get_stack_info(self) -> dict:
        """Get detailed information about the detected stack.
        
        Returns:
            Dictionary with stack information
        """
        stack = self.detect_stack()
        
        info = {
            "stack": stack.value,
            "confidence": "high" if stack != TechStack.UNKNOWN else "low",
            "indicators": []
        }
        
        if stack == TechStack.LARAVEL:
            info["indicators"] = self._get_laravel_indicators()
        elif stack == TechStack.PHOENIX:
            info["indicators"] = self._get_phoenix_indicators()
        elif stack == TechStack.PYTHON:
            info["indicators"] = self._get_python_indicators()
        
        return info
    
    def _get_laravel_indicators(self) -> list:
        """Get list of Laravel indicators found."""
        indicators = []
        
        if (self.project_path / "composer.json").exists():
            indicators.append("composer.json")
        if (self.project_path / "artisan").exists():
            indicators.append("artisan")
        if (self.project_path / "app").exists():
            indicators.append("app/ directory")
        if (self.project_path / "config" / "app.php").exists():
            indicators.append("config/app.php")
        
        return indicators
    
    def _get_phoenix_indicators(self) -> list:
        """Get list of Phoenix indicators found."""
        indicators = []
        
        if (self.project_path / "mix.exs").exists():
            indicators.append("mix.exs")
        if (self.project_path / "config" / "config.exs").exists():
            indicators.append("config/config.exs")
        if (self.project_path / "lib").exists():
            indicators.append("lib/ directory")
        
        return indicators
    
    def _get_python_indicators(self) -> list:
        """Get list of Python indicators found."""
        indicators = []
        
        if (self.project_path / "requirements.txt").exists():
            indicators.append("requirements.txt")
        if (self.project_path / "setup.py").exists():
            indicators.append("setup.py")
        if (self.project_path / "pyproject.toml").exists():
            indicators.append("pyproject.toml")
        if (self.project_path / "Pipfile").exists():
            indicators.append("Pipfile")
        
        # Check for .py files
        py_files = list(self.project_path.glob("*.py"))
        if py_files:
            indicators.append(f"{len(py_files)} .py files in root")
        
        return indicators