"""
Remediation suggestions module for AI agent security capabilities.

Maps each capability category to actionable remediation guidance for
addressing security risks identified by Bastion AI scanners.
"""

from __future__ import annotations

from typing import Any, Dict, List

from bastion.models import Capability


REMEDIATION_GUIDANCE: Dict[str, Dict[str, str]] = {
    "system_execution": {
        "summary": "Implement sandboxing and input validation for subprocess calls; avoid shell=True.",
        "details": (
            "System command execution is a critical privilege that should be tightly controlled. "
            "Implement strict input validation and sanitization before passing any user-controlled "
            "data to subprocess calls. Always use shell=False to prevent shell injection attacks. "
            "Consider using allowlists of permitted commands and arguments. Deploy the plugin in a "
            "sandboxed environment to limit the impact of any successful exploitation."
        ),
        "risk_context": (
            "Unrestricted system execution allows plugins to run arbitrary commands, potentially "
            "compromising the entire host system. This is especially dangerous when combined with "
            "network access or dynamic code execution."
        ),
    },
    "network_access": {
        "summary": "Restrict network access to known domains/IPs; implement allowlists and egress monitoring.",
        "details": (
            "Network access should be limited to explicitly approved endpoints. Implement domain and "
            "IP allowlists at the application and network levels. Log and monitor all outbound "
            "connections to detect exfiltration attempts. Use network segmentation to restrict which "
            "networks the plugin can reach. Consider using proxy servers that validate and log all "
            "traffic."
        ),
        "risk_context": (
            "Unrestricted network access allows plugins to exfiltrate sensitive data, communicate with "
            "command-and-control servers, or pivot to other systems. This is critical when combined with "
            "access to secrets or system execution capabilities."
        ),
    },
    "secret_access": {
        "summary": "Use secret managers; avoid hardcoding; implement credential rotation.",
        "details": (
            "Never hardcode secrets in source code or configuration files. Use dedicated secret management "
            "systems (e.g., HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) to store and retrieve "
            "credentials at runtime. Implement automatic credential rotation policies with regular intervals. "
            "Use environment variables for less sensitive configuration. Audit all access to secrets and "
            "implement least-privilege access controls."
        ),
        "risk_context": (
            "Exposed credentials allow attackers to impersonate the application and access protected "
            "resources. This is especially dangerous when combined with network access, allowing "
            "credentials to be exfiltrated to external systems."
        ),
    },
    "dynamic_code": {
        "summary": "Eliminate eval/exec; use safe alternatives; implement mandatory code review.",
        "details": (
            "Dynamic code execution (eval, exec, Function, etc.) is inherently unsafe and should be "
            "eliminated whenever possible. If dynamic behavior is necessary, use safer alternatives such as "
            "restricted DSLs, expression evaluators, or data-driven logic. Implement sandboxing for any "
            "remaining dynamic code. Enforce mandatory security code reviews for any dynamic execution. "
            "Consider using static code analysis tools to detect these patterns."
        ),
        "risk_context": (
            "Dynamic code execution allows attackers to inject and run arbitrary code in the plugin's "
            "execution context. Combined with network access, this enables remote code execution attacks."
        ),
    },
    "obfuscation": {
        "summary": "Manually review all obfuscated code; escalate to security team for analysis.",
        "details": (
            "Obfuscated code obscures the plugin's true functionality and makes security analysis difficult. "
            "Manually deobfuscate and analyze all obfuscated code to understand its purpose and verify "
            "its security. Tools like de4js, js-beautify, or Python AST tools can help. Escalate findings "
            "to the security team for formal review. Consider banning obfuscation entirely in your "
            "plugin policies unless justified by legitimate intellectual property concerns."
        ),
        "risk_context": (
            "Obfuscation is often a red flag for malicious code. Even legitimately obfuscated code makes "
            "security vulnerabilities harder to detect, increasing the risk of exploitable flaws going unnoticed."
        ),
    },
    "file_system_access": {
        "summary": "Restrict file system paths; use chroot/sandboxing; validate all filenames.",
        "details": (
            "Limit file system access to specific, necessary directories using allowlists. Implement "
            "path validation to prevent directory traversal attacks (../ patterns). Use chroot jails or "
            "containerization to further restrict the accessible filesystem. Validate all filename inputs "
            "before use. Implement file integrity monitoring to detect unauthorized changes. Use read-only "
            "mounts where appropriate to prevent modification of critical files."
        ),
        "risk_context": (
            "Unrestricted file system access allows plugins to read sensitive files (configs, keys, data) "
            "or modify critical system files. This is dangerous when combined with network access for "
            "data exfiltration or system execution for privilege escalation."
        ),
    },
    "sandbox_bypass": {
        "summary": "Remove all sandbox bypass flags and mechanisms; enforce strict sandboxing.",
        "details": (
            "Sandbox bypass flags (--no-sandbox, cap_sys_ptrace, etc.) completely undermine container and "
            "process isolation. Remove all such flags immediately. If a plugin requires capabilities "
            "normally restricted by sandboxing, re-architect it to use safer alternatives. Enforce sandboxing "
            "at multiple levels (container, OS, process) to provide defense-in-depth. Regularly audit "
            "container and process configurations to ensure sandbox settings are preserved."
        ),
        "risk_context": (
            "Disabling sandbox protections exposes the host system to direct exploitation. Plugins can escape "
            "isolation and access the underlying OS, affecting all other workloads and data on the system."
        ),
    },
    "install_risk": {
        "summary": "Review install scripts; pin all dependencies; verify checksums.",
        "details": (
            "Install scripts are a common attack vector. Manually review all setup.py, install.sh, "
            "postinstall hooks, and other installation code. Pin all dependency versions to known-good "
            "versions rather than using floating version ranges. Verify checksums and cryptographic signatures "
            "of downloaded dependencies. Use lock files (requirements.lock, package-lock.json, Cargo.lock) "
            "to ensure reproducible builds. Host dependencies internally if possible to avoid supply chain risks."
        ),
        "risk_context": (
            "Malicious installation scripts can compromise the build environment and inject backdoors. "
            "Unpinned dependencies are vulnerable to supply chain attacks where a compromised version is "
            "released to the public package repository."
        ),
    },
    "hardcoded_secret": {
        "summary": "Remove all hardcoded secrets; use environment variables or vault systems.",
        "details": (
            "Immediately remove all hardcoded secrets from the codebase. Use environment variables or "
            "dedicated vault systems to provide secrets at runtime. Rotate any potentially exposed credentials. "
            "Implement pre-commit hooks to prevent future secret commits. Use secret scanning tools "
            "(git-secrets, TruffleHog, Detect Secrets) to audit the repository history. If secrets were "
            "committed, perform git history surgery (git filter-branch, BFG) to remove them completely."
        ),
        "risk_context": (
            "Hardcoded secrets in source code are easily discovered through code inspection, repository access, "
            "or public repo leaks. Exposed credentials grant direct access to protected resources and APIs."
        ),
    },
    "privilege_escalation": {
        "summary": "Apply least-privilege principle; decompose plugin into smaller units.",
        "details": (
            "Reduce the plugin's privilege level by eliminating unnecessary capabilities. Apply the principle "
            "of least privilege: only request the minimum access needed for legitimate functionality. Decompose "
            "monolithic plugins into smaller, focused units with narrower privilege scopes. Implement capability-based "
            "security to grant only specific permissions rather than broad access. Use separate plugins or processes "
            "for highly privileged operations, isolating them from less critical code."
        ),
        "risk_context": (
            "Over-privileged plugins multiply the impact of exploits. A compromise affecting an over-privileged "
            "plugin grants an attacker all its privileges, potentially compromising the entire system."
        ),
    },
    "dependency_risk": {
        "summary": "Audit dependencies; pin versions; check for known vulnerabilities.",
        "details": (
            "Maintain a complete inventory of all dependencies and their versions. Regularly audit dependencies "
            "for known vulnerabilities using tools like OWASP Dependency-Check, Snyk, or safety. Pin all dependencies "
            "to specific versions in lock files to ensure reproducible builds and prevent unexpected updates. "
            "Implement an update policy that regularly upgrades dependencies to include security patches. Remove "
            "unused dependencies to reduce attack surface. Review the security posture and maintenance status of "
            "all direct and transitive dependencies."
        ),
        "risk_context": (
            "Dependencies with known vulnerabilities are a major attack vector. Transitive dependencies (dependencies "
            "of dependencies) are often overlooked, creating supply chain risks. Unmaintained or abandoned dependencies "
            "will never receive security patches."
        ),
    },
}

# Fallback guidance for unknown categories
_FALLBACK_GUIDANCE: Dict[str, str] = {
    "summary": "Review this capability and determine appropriate security controls.",
    "details": (
        "This capability represents a potential security risk. Analyze the evidence to understand what access "
        "or behavior it provides. Determine the minimum necessary access the plugin needs to function correctly. "
        "Implement appropriate controls to limit its usage, monitor its activity, and prevent abuse."
    ),
    "risk_context": (
        "Unknown or unexpected capabilities warrant investigation to prevent potential security incidents."
    ),
}


def get_remediation(category: str) -> Dict[str, str]:
    """
    Get remediation guidance for a given capability category.

    Args:
        category: The capability category string (e.g., 'system_execution', 'network_access').

    Returns:
        A dictionary with 'summary', 'details', and 'risk_context' keys.
        Returns fallback guidance if the category is not found.
    """
    return REMEDIATION_GUIDANCE.get(category, _FALLBACK_GUIDANCE.copy())


def get_all_remediations(capabilities: List[Capability]) -> List[Dict[str, Any]]:
    """
    Get remediation guidance for a list of Capability objects.

    Args:
        capabilities: A list of Capability objects from a scan result.

    Returns:
        A list of dictionaries with 'category', 'severity', and 'remediation' keys,
        where 'remediation' contains the full guidance for that category.
    """
    remediations: List[Dict[str, Any]] = []
    seen_categories: set = set()

    for capability in capabilities:
        # Avoid duplicate remediations for the same category
        if capability.category in seen_categories:
            continue

        seen_categories.add(capability.category)
        remediation = get_remediation(capability.category)

        remediations.append({
            "category": capability.category,
            "severity": capability.severity,
            "remediation": remediation,
        })

    return remediations
