#!/usr/bin/env python3
"""
Project Context Detection - Analyze current project environment and configuration
================================================================================

Detects and analyzes the current project context including:
- Project type and framework
- Technology stack and dependencies
- Project health and status
- Recent activity and development context
- Configuration and setup information
"""

import os
import json
import subprocess
import platform
import sys
import fnmatch
from pathlib import Path
from typing import Dict, Any, List, Optional, Set
from datetime import datetime, timedelta

from utils.logging import setup_logger

logger = setup_logger(__name__)


class ProjectContextDetector:
    """Analyzes current project environment and provides comprehensive context."""
    
    def __init__(self, project_root: str = None):
        self.project_root = Path(project_root) if project_root else Path.cwd()
        while not self._is_project_root(self.project_root) and self.project_root.parent != self.project_root:
            self.project_root = self.project_root.parent
        
        # Load gitignore patterns for performance optimization
        self.ignore_patterns = self._load_gitignore_patterns()
    
    def _is_project_root(self, path: Path) -> bool:
        """Check if path is a project root directory."""
        indicators = [
            'package.json', 'setup.py', 'pyproject.toml', 'Cargo.toml',
            'pom.xml', 'build.gradle', '.git', 'Makefile', 'README.md'
        ]
        return any((path / indicator).exists() for indicator in indicators)
    
    def _load_gitignore_patterns(self) -> Set[str]:
        """Load gitignore patterns for file filtering."""
        patterns = set()
        
        # Default ignore patterns for performance
        default_ignores = {
            'node_modules', '__pycache__', '.git', '.venv', 'venv', 'env',
            '.pytest_cache', '.mypy_cache', '.tox', 'dist', 'build',
            '*.pyc', '*.pyo', '*.pyd', '.DS_Store', 'Thumbs.db',
            '.coverage', '.nyc_output', 'coverage', '.sass-cache',
            '.next', '.nuxt', '.vuepress/dist', '.serverless',
            '.env.local', '.env.*.local'
        }
        patterns.update(default_ignores)
        
        # Load .gitignore if it exists
        gitignore_path = self.project_root / '.gitignore'
        if gitignore_path.exists():
            try:
                with open(gitignore_path, 'r', encoding='utf-8') as f:
                    for line in f:
                        line = line.strip()
                        if line and not line.startswith('#'):
                            # Remove leading slash and add to patterns
                            pattern = line.lstrip('/')
                            if pattern:
                                patterns.add(pattern)
            except Exception as e:
                logger.debug(f"Error reading .gitignore: {e}")
        
        return patterns
    
    def _should_ignore_path(self, path: Path, relative_to_root: Path = None) -> bool:
        """Check if a path should be ignored based on gitignore patterns."""
        if relative_to_root is None:
            try:
                relative_path = path.relative_to(self.project_root)
            except ValueError:
                return False
        else:
            relative_path = relative_to_root
        
        path_str = str(relative_path)
        path_parts = relative_path.parts
        
        for pattern in self.ignore_patterns:
            # Check if pattern matches the full path or any part
            if fnmatch.fnmatch(path_str, pattern):
                return True
            if fnmatch.fnmatch(path.name, pattern):
                return True
            # Check if any parent directory matches the pattern
            for part in path_parts:
                if fnmatch.fnmatch(part, pattern):
                    return True
        
        return False
    
    def _detect_operating_system(self) -> Dict[str, Any]:
        """Detect detailed operating system information."""
        try:
            os_info = {
                "platform": platform.system(),
                "platform_release": platform.release(),
                "platform_version": platform.version(),
                "architecture": platform.machine(),
                "processor": platform.processor(),
                "python_version": platform.python_version(),
                "python_implementation": platform.python_implementation(),
                "node": platform.node(),
                "detailed_platform": platform.platform(),
                "system_alias": None,
                "distribution": None,
                "distribution_version": None
            }
            
            # Add more specific OS details
            if platform.system().lower() == "linux":
                try:
                    # Try to get Linux distribution info
                    import distro
                    os_info["distribution"] = distro.name()
                    os_info["distribution_version"] = distro.version()
                    os_info["system_alias"] = f"{distro.name()} {distro.version()}"
                except ImportError:
                    # Fallback for older systems or when distro package not available
                    try:
                        with open('/etc/os-release', 'r') as f:
                            os_release = f.read()
                            # Extract NAME and VERSION_ID
                            for line in os_release.split('\n'):
                                if line.startswith('NAME='):
                                    os_info["distribution"] = line.split('=', 1)[1].strip('"')
                                elif line.startswith('VERSION_ID='):
                                    os_info["distribution_version"] = line.split('=', 1)[1].strip('"')
                            if os_info["distribution"]:
                                os_info["system_alias"] = f"{os_info['distribution']} {os_info.get('distribution_version', '')}"
                    except:
                        os_info["system_alias"] = f"Linux {platform.release()}"
            elif platform.system().lower() == "darwin":
                # macOS
                mac_version = platform.mac_ver()[0]
                os_info["system_alias"] = f"macOS {mac_version}"
                os_info["distribution"] = "macOS"
                os_info["distribution_version"] = mac_version
            elif platform.system().lower() == "windows":
                # Windows
                win_version = platform.win32_ver()
                os_info["system_alias"] = f"Windows {win_version[0]} {win_version[1]}"
                os_info["distribution"] = "Windows"
                os_info["distribution_version"] = win_version[0]
            
            # Add environment info
            os_info["is_container"] = self._detect_container_environment()
            os_info["is_wsl"] = self._detect_wsl()
            os_info["is_codespace"] = self._detect_codespace()
            
            return os_info
            
        except Exception as e:
            logger.error(f"Error detecting OS information: {e}")
            return {
                "platform": platform.system(),
                "error": str(e),
                "fallback": True
            }
    
    def _detect_container_environment(self) -> bool:
        """Detect if running in a container environment."""
        try:
            # Check for container indicators
            container_indicators = [
                os.path.exists('/.dockerenv'),
                os.path.exists('/run/.containerenv'),
                os.environ.get('container') is not None,
                os.environ.get('KUBERNETES_SERVICE_HOST') is not None
            ]
            return any(container_indicators)
        except:
            return False
    
    def _detect_wsl(self) -> bool:
        """Detect if running in Windows Subsystem for Linux."""
        try:
            if platform.system().lower() != "linux":
                return False
            
            # Check for WSL indicators
            wsl_indicators = [
                'microsoft' in platform.uname().release.lower(),
                'wsl' in platform.uname().release.lower(),
                os.path.exists('/proc/version') and 'microsoft' in open('/proc/version').read().lower()
            ]
            return any(wsl_indicators)
        except:
            return False
    
    def _detect_codespace(self) -> bool:
        """Detect if running in GitHub Codespaces."""
        try:
            codespace_indicators = [
                os.environ.get('CODESPACES') is not None,
                os.environ.get('GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN') is not None,
                os.path.exists('/workspaces')
            ]
            return any(codespace_indicators)
        except:
            return False
    
    def detect_project_context(self) -> Dict[str, Any]:
        """Get comprehensive project context information."""
        try:
            context = {
                "project_root": str(self.project_root),
                "project_name": self._detect_project_name(),
                "project_type": self._detect_project_type(),
                "tech_stack": self._detect_tech_stack(),
                "framework_info": self._detect_framework(),
                "dependencies": self._analyze_dependencies(), 
                "project_structure": self._analyze_project_structure(),
                "git_status": self._get_git_status(),
                "recent_activity": self._analyze_recent_activity(),
                "project_health": self._assess_project_health(),
                "configuration": self._detect_configuration(),
                "documentation": self._analyze_documentation(),
                "testing": self._detect_testing_setup(),
                "build_system": self._detect_build_system(),
                "deployment": self._detect_deployment_config(),
                "project_purpose": self._detect_project_purpose(),
                "development_patterns": self._analyze_development_patterns(),
                "recent_commits": self._analyze_recent_commits(),
                "operating_system": self._detect_operating_system()
            }
            
            context["summary"] = self._generate_project_summary(context)
            return context
            
        except Exception as e:
            logger.error(f"Error detecting project context: {e}")
            return {"error": str(e), "project_root": str(self.project_root)}
    
    def _detect_project_name(self) -> str:
        """Detect project name from various sources."""
        # Try package.json first
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    return data.get("name", self.project_root.name)
            except:
                pass
        
        # Try setup.py
        setup_py = self.project_root / "setup.py"
        if setup_py.exists():
            try:
                with open(setup_py) as f:
                    content = f.read()
                    import re
                    match = re.search(r'name\s*=\s*["\']([^"\']+)["\']', content)
                    if match:
                        return match.group(1)
            except:
                pass
        
        # Try pyproject.toml
        pyproject = self.project_root / "pyproject.toml"
        if pyproject.exists():
            try:
                with open(pyproject) as f:
                    content = f.read()
                    import re
                    match = re.search(r'name\s*=\s*["\']([^"\']+)["\']', content)
                    if match:
                        return match.group(1)
            except:
                pass
        
        return self.project_root.name
    
    def _detect_project_type(self) -> Dict[str, Any]:
        """Detect project type and primary technology."""
        types = []
        
        # Node.js/JavaScript/TypeScript
        if (self.project_root / "package.json").exists():
            types.append("Node.js Application")
            if (self.project_root / "tsconfig.json").exists():
                types.append("TypeScript")
        
        # Python
        if any((self.project_root / f).exists() for f in ["setup.py", "requirements.txt", "pyproject.toml"]):
            types.append("Python Project")
        
        # Rust
        if (self.project_root / "Cargo.toml").exists():
            types.append("Rust Project")
        
        # Go
        if (self.project_root / "go.mod").exists():
            types.append("Go Project")
        
        # Java
        if any((self.project_root / f).exists() for f in ["pom.xml", "build.gradle"]):
            types.append("Java Project")
        
        # General indicators
        if (self.project_root / ".git").exists():
            types.append("Git Repository")
        
        return {
            "primary_type": types[0] if types else "General Project",
            "all_types": types,
            "is_monorepo": self._detect_monorepo()
        }
    
    def _detect_tech_stack(self) -> Dict[str, Any]:
        """Analyze technology stack."""
        stack = {
            "languages": [],
            "frameworks": [],
            "databases": [],
            "tools": []
        }
        
        # Language detection from files
        language_extensions = {
            ".js": "JavaScript", ".ts": "TypeScript", ".py": "Python",
            ".rs": "Rust", ".go": "Go", ".java": "Java", ".cpp": "C++",
            ".c": "C", ".cs": "C#", ".rb": "Ruby", ".php": "PHP"
        }
        
        for ext, lang in language_extensions.items():
            if list(self.project_root.rglob(f"*{ext}")):
                stack["languages"].append(lang)
        
        # Framework detection
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    deps = {**data.get("dependencies", {}), **data.get("devDependencies", {})}
                    
                    frameworks = {
                        "react": "React", "vue": "Vue.js", "angular": "Angular",
                        "express": "Express.js", "fastify": "Fastify", "koa": "Koa",
                        "next": "Next.js", "nuxt": "Nuxt.js", "gatsby": "Gatsby",
                        "svelte": "Svelte", "solid-js": "SolidJS"
                    }
                    
                    for dep, framework in frameworks.items():
                        if dep in deps:
                            stack["frameworks"].append(framework)
            except:
                pass
        
        return stack
    
    def _detect_framework(self) -> Dict[str, Any]:
        """Detect specific framework information."""
        framework_info = {"type": "Custom", "version": None, "config": []}
        
        # Next.js
        if (self.project_root / "next.config.js").exists():
            framework_info.update({"type": "Next.js", "config": ["next.config.js"]})
        
        # Express.js (check for typical Express patterns)
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    if "express" in data.get("dependencies", {}):
                        framework_info.update({"type": "Express.js"})
            except:
                pass
        
        # Django
        if (self.project_root / "manage.py").exists():
            framework_info.update({"type": "Django", "config": ["manage.py"]})
        
        # Flask (check for app.py or typical Flask structure)
        if (self.project_root / "app.py").exists():
            framework_info.update({"type": "Flask"})
        
        return framework_info
    
    def _analyze_dependencies(self) -> Dict[str, Any]:
        """Analyze project dependencies."""
        deps_info = {"total": 0, "production": 0, "development": 0, "outdated": 0}
        
        # Node.js dependencies
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    prod_deps = data.get("dependencies", {})
                    dev_deps = data.get("devDependencies", {})
                    
                    deps_info.update({
                        "production": len(prod_deps),
                        "development": len(dev_deps),
                        "total": len(prod_deps) + len(dev_deps),
                        "key_dependencies": list(prod_deps.keys())[:10]
                    })
            except:
                pass
        
        # Python dependencies
        requirements_txt = self.project_root / "requirements.txt"
        if requirements_txt.exists():
            try:
                with open(requirements_txt) as f:
                    lines = [line.strip() for line in f if line.strip() and not line.startswith("#")]
                    deps_info.update({
                        "python_requirements": len(lines),
                        "total": deps_info.get("total", 0) + len(lines)
                    })
            except:
                pass
        
        return deps_info
    
    def _analyze_project_structure(self) -> Dict[str, Any]:
        """Analyze project directory structure."""
        structure = {
            "total_files": 0,
            "directories": [],
            "key_files": [],
            "source_dirs": [],
            "config_files": []
        }
        
        try:
            # Count files and analyze structure (with limits for performance)
            file_count = 0
            max_files_to_scan = 5000  # Limit for performance
            
            for root, dirs, files in os.walk(self.project_root):
                root_path = Path(root)
                rel_root = root_path.relative_to(self.project_root)
                
                # Filter directories using gitignore patterns
                dirs[:] = [d for d in dirs if not self._should_ignore_path(root_path / d)]
                
                # Filter files using gitignore patterns
                filtered_files = [f for f in files if not self._should_ignore_path(root_path / f)]
                
                if rel_root != Path('.'):
                    structure["directories"].append(str(rel_root))
                
                structure["total_files"] += len(filtered_files)
                file_count += len(filtered_files)
                
                # Stop if we've scanned too many files (performance optimization)
                if file_count > max_files_to_scan:
                    break
                
                # Identify key files in root
                if rel_root == Path('.'):
                    for file in filtered_files:
                        if file in ['README.md', 'package.json', 'setup.py', 'Dockerfile', 'docker-compose.yml']:
                            structure["key_files"].append(file)
                        if file.endswith(('.json', '.yml', '.yaml', '.toml', '.ini')):
                            structure["config_files"].append(file)
            
            # Identify source directories
            common_source_dirs = ['src', 'lib', 'app', 'components', 'pages', 'utils', 'services']
            for dir_name in common_source_dirs:
                if (self.project_root / dir_name).is_dir():
                    structure["source_dirs"].append(dir_name)
            
        except Exception as e:
            logger.error(f"Error analyzing project structure: {e}")
        
        return structure
    
    def _get_git_status(self) -> Dict[str, Any]:
        """Get Git repository status information."""
        git_info = {"is_git_repo": False}
        
        if not (self.project_root / ".git").exists():
            return git_info
        
        try:
            # Basic git info
            git_info["is_git_repo"] = True
            
            # Current branch
            result = subprocess.run(['git', 'branch', '--show-current'], 
                                  cwd=self.project_root, capture_output=True, text=True, timeout=10)
            if result.returncode == 0:
                git_info["current_branch"] = result.stdout.strip()
            
            # Repository status
            result = subprocess.run(['git', 'status', '--porcelain'], 
                                  cwd=self.project_root, capture_output=True, text=True, timeout=10)
            if result.returncode == 0:
                status_lines = result.stdout.strip().split('\n') if result.stdout.strip() else []
                git_info["has_changes"] = len(status_lines) > 0
                git_info["changed_files"] = len(status_lines)
            
            # Recent commits
            result = subprocess.run(['git', 'log', '--oneline', '-5', '--format=%h %s'], 
                                  cwd=self.project_root, capture_output=True, text=True, timeout=15)
            if result.returncode == 0:
                commits = result.stdout.strip().split('\n') if result.stdout.strip() else []
                git_info["recent_commits"] = commits[:3]
            
        except Exception as e:
            logger.error(f"Error getting git status: {e}")
        
        return git_info
    
    def _analyze_recent_activity(self) -> Dict[str, Any]:
        """Analyze recent project activity."""
        activity = {"last_modified": None, "active_files": [], "recent_changes": 0}
        
        try:
            # Find recently modified files (last 7 days, with performance limits)
            recent_files = []
            cutoff_time = datetime.now() - timedelta(days=7)
            files_checked = 0
            max_files_to_check = 1000  # Limit for performance
            
            for root, dirs, files in os.walk(self.project_root):
                root_path = Path(root)
                
                # Filter directories using gitignore patterns
                dirs[:] = [d for d in dirs if not self._should_ignore_path(root_path / d)]
                
                # Filter files using gitignore patterns
                filtered_files = [f for f in files if not self._should_ignore_path(root_path / f)]
                
                for file in filtered_files:
                    files_checked += 1
                    if files_checked > max_files_to_check:
                        break
                        
                    file_path = root_path / file
                    try:
                        mod_time = datetime.fromtimestamp(file_path.stat().st_mtime)
                        if mod_time > cutoff_time:
                            recent_files.append({
                                "file": str(file_path.relative_to(self.project_root)),
                                "modified": mod_time.isoformat()
                            })
                    except:
                        continue
            
            activity.update({
                "recent_changes": len(recent_files),
                "active_files": [f["file"] for f in sorted(recent_files, key=lambda x: x["modified"], reverse=True)[:10]]
            })
            
            if recent_files:
                activity["last_modified"] = sorted(recent_files, key=lambda x: x["modified"], reverse=True)[0]["modified"]
        
        except Exception as e:
            logger.error(f"Error analyzing recent activity: {e}")
        
        return activity
    
    def _assess_project_health(self) -> Dict[str, Any]:
        """Assess overall project health and status."""
        health = {
            "status": "unknown",
            "score": 0,
            "indicators": []
        }
        
        score = 0
        indicators = []
        
        # Check for essential files
        if (self.project_root / "README.md").exists():
            score += 20
            indicators.append("✅ Documentation present")
        else:
            indicators.append("⚠️ Missing README")
        
        # Check for version control
        if (self.project_root / ".git").exists():
            score += 20
            indicators.append("✅ Version control active")
        
        # Check for dependencies management
        if any((self.project_root / f).exists() for f in ["package.json", "requirements.txt", "Cargo.toml"]):
            score += 20
            indicators.append("✅ Dependencies managed")
        
        # Check for testing
        test_indicators = ["test", "spec", "__test__", "tests"]
        has_tests = any(list(self.project_root.rglob(f"*{indicator}*")) for indicator in test_indicators)
        if has_tests:
            score += 20
            indicators.append("✅ Tests present")
        else:
            indicators.append("⚠️ No tests detected")
        
        # Check for configuration
        config_files = [".gitignore", "tsconfig.json", ".eslintrc", "pyproject.toml"]
        config_present = sum(1 for f in config_files if (self.project_root / f).exists())
        if config_present >= 2:
            score += 20
            indicators.append("✅ Well configured")
        
        # Determine status
        if score >= 80:
            health["status"] = "excellent"
        elif score >= 60:
            health["status"] = "good"
        elif score >= 40:
            health["status"] = "fair"
        else:
            health["status"] = "needs_improvement"
        
        health.update({"score": score, "indicators": indicators})
        return health
    
    def _detect_configuration(self) -> List[str]:
        """Detect configuration files present."""
        config_files = [
            "package.json", "tsconfig.json", ".eslintrc", ".prettierrc",
            "setup.py", "pyproject.toml", "requirements.txt", ".gitignore",
            "Dockerfile", "docker-compose.yml", ".env", "Makefile"
        ]
        
        return [f for f in config_files if (self.project_root / f).exists()]
    
    def _analyze_documentation(self) -> Dict[str, Any]:
        """Analyze documentation status."""
        docs = {"has_readme": False, "doc_files": [], "coverage": "none"}
        
        readme_files = ["README.md", "README.rst", "README.txt"]
        docs["has_readme"] = any((self.project_root / f).exists() for f in readme_files)
        
        doc_patterns = ["*.md", "*.rst", "docs/*", "doc/*", "CHANGELOG*", "LICENSE*"]
        doc_files = []
        for pattern in doc_patterns:
            doc_files.extend(list(self.project_root.glob(pattern)))
        
        docs["doc_files"] = [str(f.relative_to(self.project_root)) for f in doc_files]
        
        # Assess coverage
        if len(doc_files) >= 5:
            docs["coverage"] = "comprehensive"
        elif len(doc_files) >= 2:
            docs["coverage"] = "basic"
        elif docs["has_readme"]:
            docs["coverage"] = "minimal"
        
        return docs
    
    def _detect_testing_setup(self) -> Dict[str, Any]:
        """Detect testing framework and setup."""
        testing = {"framework": None, "test_files": 0, "coverage": False}
        
        # Check for test files
        test_patterns = ["*test*", "*spec*", "tests/*", "__test__/*"]
        test_files = []
        for pattern in test_patterns:
            test_files.extend(list(self.project_root.rglob(pattern)))
        
        testing["test_files"] = len([f for f in test_files if f.is_file()])
        
        # Detect framework from package.json
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    deps = {**data.get("dependencies", {}), **data.get("devDependencies", {})}
                    
                    test_frameworks = {
                        "jest": "Jest", "mocha": "Mocha", "jasmine": "Jasmine",
                        "cypress": "Cypress", "playwright": "Playwright"
                    }
                    
                    for dep, framework in test_frameworks.items():
                        if dep in deps:
                            testing["framework"] = framework
                            break
            except:
                pass
        
        # Check for Python testing
        if (self.project_root / "pytest.ini").exists() or any("pytest" in str(f) for f in test_files):
            testing["framework"] = "pytest"
        
        return testing
    
    def _detect_build_system(self) -> Dict[str, Any]:
        """Detect build system and scripts."""
        build = {"system": None, "scripts": [], "has_build": False}
        
        # Check package.json scripts
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json) as f:
                    data = json.load(f)
                    scripts = data.get("scripts", {})
                    build["scripts"] = list(scripts.keys())
                    build["has_build"] = "build" in scripts
                    
                    if scripts:
                        build["system"] = "npm/yarn"
            except:
                pass
        
        # Check for other build systems
        if (self.project_root / "Makefile").exists():
            build["system"] = "Make"
        elif (self.project_root / "setup.py").exists():
            build["system"] = "Python setuptools"
        elif (self.project_root / "Cargo.toml").exists():
            build["system"] = "Cargo"
        
        return build
    
    def _detect_deployment_config(self) -> List[str]:
        """Detect deployment configuration files."""
        deploy_files = [
            "Dockerfile", "docker-compose.yml", ".dockerignore",
            "vercel.json", "netlify.toml", ".github/workflows",
            "heroku.yml", "app.yaml", "serverless.yml"
        ]
        
        found = []
        for file in deploy_files:
            if (self.project_root / file).exists():
                found.append(file)
        
        return found
    
    def _detect_monorepo(self) -> bool:
        """Check if this is a monorepo structure."""
        # Look for common monorepo indicators
        monorepo_indicators = [
            "lerna.json", "nx.json", "rush.json", "packages",
            "apps", "libs", "workspace", "projects"
        ]
        
        for indicator in monorepo_indicators:
            if (self.project_root / indicator).exists():
                return True
        
        # Check for multiple package.json files
        package_files = list(self.project_root.rglob("package.json"))
        return len(package_files) > 1
    
    def _analyze_recent_commits(self) -> Dict[str, Any]:
        """Analyze recent git commits for development context."""
        commits_info = {"recent_commits": [], "development_themes": [], "commit_velocity": 0}
        
        if not (self.project_root / ".git").exists():
            return commits_info
        
        try:
            # Get recent commits with more detail
            result = subprocess.run([
                'git', 'log', '--oneline', '-5', 
                '--format=%h|%s|%an|%ar|%ad', '--date=iso'
            ], cwd=self.project_root, capture_output=True, text=True, timeout=15)
            
            if result.returncode == 0 and result.stdout.strip():
                commit_lines = result.stdout.strip().split('\n')
                commits = []
                
                for line in commit_lines:
                    parts = line.split('|')
                    if len(parts) >= 4:
                        commits.append({
                            "hash": parts[0],
                            "message": parts[1],
                            "author": parts[2],
                            "relative_date": parts[3],
                            "absolute_date": parts[4] if len(parts) > 4 else ""
                        })
                
                commits_info["recent_commits"] = commits[:10]
                commits_info["commit_velocity"] = len(commits)
                
                # Analyze commit themes
                commit_types = {}
                for commit in commits:
                    msg = commit["message"].lower()
                    if msg.startswith(("feat:", "feature:")):
                        commit_types["features"] = commit_types.get("features", 0) + 1
                    elif msg.startswith(("fix:", "bug:")):
                        commit_types["fixes"] = commit_types.get("fixes", 0) + 1
                    elif msg.startswith(("refactor:", "refact:")):
                        commit_types["refactoring"] = commit_types.get("refactoring", 0) + 1
                    elif msg.startswith(("docs:", "doc:")):
                        commit_types["documentation"] = commit_types.get("documentation", 0) + 1
                    elif msg.startswith(("test:", "tests:")):
                        commit_types["testing"] = commit_types.get("testing", 0) + 1
                    elif msg.startswith(("chore:", "misc:")):
                        commit_types["maintenance"] = commit_types.get("maintenance", 0) + 1
                
                commits_info["development_themes"] = commit_types
                
        except Exception as e:
            logger.error(f"Error analyzing recent commits: {e}")
        
        return commits_info
    
    def _detect_project_purpose(self) -> Dict[str, Any]:
        """Detect project purpose and mission from README and package.json."""
        purpose_info = {
            "mission": "Unknown",
            "description": "No description available",
            "key_features": [],
            "target_audience": "Unknown"
        }
        
        # Try to extract from README
        readme_paths = ["README.md", "README.rst", "README.txt"]
        for readme_file in readme_paths:
            readme_path = self.project_root / readme_file
            if readme_path.exists():
                try:
                    with open(readme_path, 'r', encoding='utf-8') as f:
                        content = f.read()
                        
                    # Extract description from first paragraph
                    lines = content.split('\n')
                    description_lines = []
                    started = False
                    
                    for line in lines:
                        line = line.strip()
                        if not line:
                            if started and description_lines:
                                break
                            continue
                        if line.startswith('#'):
                            started = True
                            continue
                        if started and not line.startswith(('![', '[', '```', '---')):
                            description_lines.append(line)
                            if len(description_lines) >= 3:  # Get first few sentences
                                break
                    
                    if description_lines:
                        purpose_info["description"] = ' '.join(description_lines)
                    
                    # Look for feature sections
                    feature_section = False
                    features = []
                    for line in lines:
                        if any(keyword in line.lower() for keyword in ['features', 'capabilities', 'what it does']):
                            feature_section = True
                            continue
                        if feature_section and line.strip().startswith(('- ', '* ', '1. ', '2. ')):
                            feature = line.strip().lstrip('- *123456789. ')
                            if len(feature) > 10:  # Skip very short items
                                features.append(feature)
                        elif feature_section and line.strip().startswith('#'):
                            break
                    
                    purpose_info["key_features"] = features[:5]
                    
                except Exception as e:
                    logger.error(f"Error reading README: {e}")
        
        # Try package.json for additional context
        package_json = self.project_root / "package.json"
        if package_json.exists():
            try:
                with open(package_json, 'r') as f:
                    data = json.load(f)
                    
                if data.get("description") and not purpose_info["description"].startswith("No description"):
                    purpose_info["description"] = data["description"]
                
                # Keywords can indicate target audience
                keywords = data.get("keywords", [])
                if keywords:
                    purpose_info["keywords"] = keywords[:10]
                    
            except Exception as e:
                logger.error(f"Error reading package.json: {e}")
        
        return purpose_info
    
    def _analyze_development_patterns(self) -> Dict[str, Any]:
        """Analyze development patterns and current phase."""
        patterns = {
            "development_phase": "unknown",
            "recent_focus": [],
            "code_quality_indicators": {},
            "development_velocity": "unknown"
        }
        
        try:
            # Analyze commit patterns
            commits_info = self._analyze_recent_commits()
            commit_themes = commits_info.get("development_themes", {})
            
            # Determine development phase based on commit patterns
            total_commits = sum(commit_themes.values())
            if total_commits > 0:
                feature_ratio = commit_themes.get("features", 0) / total_commits
                fix_ratio = commit_themes.get("fixes", 0) / total_commits
                refactor_ratio = commit_themes.get("refactoring", 0) / total_commits
                
                if feature_ratio > 0.4:
                    patterns["development_phase"] = "active_feature_development"
                elif fix_ratio > 0.4:
                    patterns["development_phase"] = "stabilization"
                elif refactor_ratio > 0.3:
                    patterns["development_phase"] = "refactoring_and_optimization"
                else:
                    patterns["development_phase"] = "maintenance"
                
                # Recent focus areas
                focus_areas = []
                for theme, count in sorted(commit_themes.items(), key=lambda x: x[1], reverse=True):
                    if count > 0:
                        focus_areas.append(f"{theme} ({count} commits)")
                patterns["recent_focus"] = focus_areas[:3]
            
            # Development velocity
            commit_velocity = commits_info.get("commit_velocity", 0)
            if commit_velocity > 15:
                patterns["development_velocity"] = "high"
            elif commit_velocity > 8:
                patterns["development_velocity"] = "moderate"  
            elif commit_velocity > 3:
                patterns["development_velocity"] = "low"
            else:
                patterns["development_velocity"] = "minimal"
                
        except Exception as e:
            logger.error(f"Error analyzing development patterns: {e}")
        
        return patterns
    
    def _generate_project_summary(self, context: Dict[str, Any]) -> Dict[str, Any]:
        """Generate a comprehensive project summary."""
        return {
            "name": context["project_name"],
            "type": context["project_type"]["primary_type"],
            "health_status": context["project_health"]["status"],
            "health_score": context["project_health"]["score"],
            "has_tests": context["testing"]["test_files"] > 0,
            "has_docs": context["documentation"]["has_readme"],
            "git_managed": context["git_status"]["is_git_repo"],
            "recent_activity": context["recent_activity"]["recent_changes"] > 0,
            "tech_stack": context["tech_stack"]["languages"][:3],
            "framework": context["framework_info"]["type"],
            "mission": context.get("project_purpose", {}).get("description", "Unknown"),
            "development_phase": context.get("development_patterns", {}).get("development_phase", "unknown"),
            "development_velocity": context.get("development_patterns", {}).get("development_velocity", "unknown"),
            "recent_focus": context.get("development_patterns", {}).get("recent_focus", [])
        }


def get_project_context_detector(project_root: str = None) -> ProjectContextDetector:
    """Get project context detector instance."""
    return ProjectContextDetector(project_root)


if __name__ == "__main__":
    detector = get_project_context_detector()
    context = detector.detect_project_context()
    print(json.dumps(context, indent=2))