"""Default built-in security policies."""

from __future__ import annotations

from mergeguide.engine.rules import Rule, RuleType, Severity

from .schema import Policy, PolicyFile, PolicyMetadata, PolicyRule

# Default policies as a PolicyFile
DEFAULT_POLICY_FILE = PolicyFile(
    version="1.0",
    metadata=PolicyMetadata(
        name="MergeGuide Default Policies",
        description="Built-in security and code quality policies",
        author="MergeGuide",
        url="https://github.com/MergeGuide/mergeguide",
    ),
    policies=[
        Policy(
            id="no-hardcoded-secrets",
            name="No Hardcoded Secrets",
            description="Detect potential hardcoded API keys, passwords, and tokens",
            severity="error",
            languages=["*"],
            rules=[
                PolicyRule(
                    pattern=r"(?i)(api[_-]?key|apikey|api_secret|access[_-]?key|client[_-]?secret)\s*[=:]\s*['\"][a-zA-Z0-9_\-]{8,}['\"]",
                    message="Potential hardcoded API key detected",
                    flags="i",
                    remediation="Use environment variables or a secrets manager instead",
                ),
                PolicyRule(
                    pattern=r"(?i)(password|passwd|pwd)\s*[=:]\s*['\"][^'\"]{4,}['\"]",
                    message="Potential hardcoded password detected",
                    flags="i",
                    remediation="Use environment variables or a secrets manager instead",
                ),
                PolicyRule(
                    pattern=r"(?i)(secret|token|auth[_-]?token|bearer)\s*[=:]\s*['\"][a-zA-Z0-9_\-]{8,}['\"]",
                    message="Potential hardcoded secret or token detected",
                    flags="i",
                    remediation="Use environment variables or a secrets manager instead",
                ),
                PolicyRule(
                    pattern=r"(?i)(aws_access_key_id|aws_secret_access_key)\s*[=:]\s*['\"][A-Z0-9]{16,}['\"]",
                    message="Potential hardcoded AWS credentials detected",
                    flags="i",
                    remediation="Use AWS IAM roles or environment variables instead",
                ),
                PolicyRule(
                    pattern=r"-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----",
                    message="Private key detected in source code",
                    remediation="Store private keys in a secure secrets manager",
                ),
                PolicyRule(
                    pattern=r"['\"](?:sk|pk|api|key|token|ghp|gho|ghu|ghs|ghr|glpat|pypi|npm|slack|xox[baprs])[_\-]?[a-zA-Z0-9]{8,}['\"]",
                    message="Potential API key with known prefix detected",
                    remediation="Use environment variables or a secrets manager instead",
                ),
            ],
        ),
        Policy(
            id="no-console-log",
            name="No Console Log in Production",
            description="Prevent console.log statements in production code",
            severity="warning",
            languages=["javascript", "typescript"],
            rules=[
                PolicyRule(
                    pattern=r"console\.(log|debug|info|warn|error)\s*\(",
                    message="console.log statement detected",
                    remediation="Use a proper logging library with configurable log levels",
                ),
            ],
        ),
        Policy(
            id="no-todo-in-code",
            name="No TODO Comments",
            description="Flag TODO and FIXME comments for tracking",
            severity="info",
            languages=["*"],
            rules=[
                PolicyRule(
                    pattern=r"(?i)\b(TODO|FIXME|HACK|XXX)\b[:\s]",
                    message="TODO/FIXME comment detected",
                    flags="i",
                    remediation="Create a tracked issue instead of leaving TODO comments",
                ),
            ],
        ),
        Policy(
            id="no-debug-statements",
            name="No Debug Statements",
            description="Detect debug statements that shouldn't be in production",
            severity="warning",
            languages=["python"],
            rules=[
                PolicyRule(
                    pattern=r"\bbreakpoint\s*\(\s*\)",
                    message="Python breakpoint() detected",
                    remediation="Remove debug breakpoints before committing",
                ),
                PolicyRule(
                    pattern=r"\bpdb\.set_trace\s*\(\s*\)",
                    message="Python debugger statement detected",
                    remediation="Remove pdb.set_trace() before committing",
                ),
                PolicyRule(
                    pattern=r"\bipdb\.set_trace\s*\(\s*\)",
                    message="Python debugger statement detected",
                    remediation="Remove ipdb.set_trace() before committing",
                ),
            ],
        ),
        Policy(
            id="no-unsafe-regex",
            name="No Unsafe Regular Expressions",
            description="Detect potentially unsafe regex patterns (ReDoS)",
            severity="warning",
            languages=["*"],
            rules=[
                PolicyRule(
                    pattern=r"\(\.\*\)\+|\(\.\+\)\*|\(\.\+\)\+",
                    message="Potentially unsafe nested quantifier in regex (ReDoS risk)",
                    remediation="Simplify the regex to avoid catastrophic backtracking",
                ),
            ],
        ),
        Policy(
            id="no-sql-string-concat",
            name="No SQL String Concatenation",
            description="Detect potential SQL injection vulnerabilities",
            severity="error",
            languages=["python", "javascript", "typescript", "java"],
            rules=[
                PolicyRule(
                    pattern=r"(?i)(SELECT|INSERT|UPDATE|DELETE|DROP|ALTER)\s+.*\+\s*['\"]?\s*\+",
                    message="Potential SQL injection via string concatenation",
                    flags="i",
                    remediation="Use parameterized queries or an ORM",
                ),
                PolicyRule(
                    pattern=r"(?i)f['\"].*\{.*\}.*(SELECT|INSERT|UPDATE|DELETE)",
                    message="Potential SQL injection via f-string",
                    flags="i",
                    remediation="Use parameterized queries instead of string formatting",
                ),
            ],
        ),
        Policy(
            id="no-eval",
            name="No Eval Statements",
            description="Detect dangerous eval() usage",
            severity="error",
            languages=["python", "javascript", "typescript"],
            rules=[
                PolicyRule(
                    pattern=r"\beval\s*\(",
                    message="Dangerous eval() usage detected",
                    remediation=(
                        "Avoid eval() - use safe alternatives like "
                        "JSON.parse() or ast.literal_eval()"
                    ),
                ),
            ],
        ),
    ],
)


def get_default_policies() -> PolicyFile:
    """Get the default built-in policies.

    Returns:
        PolicyFile containing all default policies
    """
    return DEFAULT_POLICY_FILE


def get_default_rules() -> list[Rule]:
    """Get default policies as Rule objects for the engine.

    Returns:
        List of Rule objects
    """
    rules: list[Rule] = []

    for policy in DEFAULT_POLICY_FILE.policies:
        if not policy.enabled:
            continue

        for i, rule_def in enumerate(policy.rules):
            rule_id = f"{policy.id}-{i}" if len(policy.rules) > 1 else policy.id
            rules.append(
                Rule(
                    id=rule_id,
                    name=policy.name,
                    pattern=rule_def.pattern,
                    message=rule_def.message,
                    severity=Severity.from_string(policy.severity),
                    rule_type=RuleType.REGEX,
                    languages=policy.languages,
                    remediation=rule_def.remediation,
                    flags=rule_def.flags,
                )
            )

    return rules


# YAML representation for reference/export
DEFAULT_POLICIES_YAML = """
version: "1.0"

metadata:
  name: "MergeGuide Default Policies"
  description: "Built-in security and code quality policies"
  author: "MergeGuide"
  url: "https://github.com/MergeGuide/mergeguide"

policies:
  - id: "no-hardcoded-secrets"
    name: "No Hardcoded Secrets"
    description: "Detect potential hardcoded API keys, passwords, and tokens"
    severity: error
    languages: ["*"]
    rules:
      - pattern: "(?i)(api[_-]?key|apikey|api_secret)\\\\s*[=:]\\\\s*['\"][a-zA-Z0-9_\\\\-]{16,}['\"]"
        flags: "i"
        message: "Potential hardcoded API key detected"
        remediation: "Use environment variables or a secrets manager instead"
      - pattern: "(?i)(password|passwd|pwd)\\\\s*[=:]\\\\s*['\"][^'\"]{4,}['\"]"
        flags: "i"
        message: "Potential hardcoded password detected"
        remediation: "Use environment variables or a secrets manager instead"
      - pattern: "(?i)(secret|token|auth[_-]?token)\\\\s*[=:]\\\\s*['\"][a-zA-Z0-9_\\\\-]{8,}['\"]"
        flags: "i"
        message: "Potential hardcoded secret or token detected"
        remediation: "Use environment variables or a secrets manager instead"
      - pattern: "-----BEGIN\\\\s+(RSA\\\\s+)?PRIVATE\\\\s+KEY-----"
        message: "Private key detected in source code"
        remediation: "Store private keys in a secure secrets manager"

  - id: "no-console-log"
    name: "No Console Log in Production"
    description: "Prevent console.log statements in production code"
    severity: warning
    languages: ["javascript", "typescript"]
    rules:
      - pattern: "console\\\\.(log|debug|info|warn|error)\\\\s*\\\\("
        message: "console.log statement detected"
        remediation: "Use a proper logging library with configurable log levels"

  - id: "no-todo-in-code"
    name: "No TODO Comments"
    description: "Flag TODO and FIXME comments for tracking"
    severity: info
    languages: ["*"]
    rules:
      - pattern: "(?i)\\\\b(TODO|FIXME|HACK|XXX)\\\\b[:\\\\s]"
        flags: "i"
        message: "TODO/FIXME comment detected"
        remediation: "Create a tracked issue instead of leaving TODO comments"

  - id: "no-debug-statements"
    name: "No Debug Statements"
    description: "Detect debug statements that shouldn't be in production"
    severity: warning
    languages: ["python"]
    rules:
      - pattern: "\\\\bbreakpoint\\\\s*\\\\(\\\\s*\\\\)"
        message: "Python breakpoint() detected"
        remediation: "Remove debug breakpoints before committing"
      - pattern: "\\\\bpdb\\\\.set_trace\\\\s*\\\\(\\\\s*\\\\)"
        message: "Python debugger statement detected"
        remediation: "Remove pdb.set_trace() before committing"

  - id: "no-eval"
    name: "No Eval Statements"
    description: "Detect dangerous eval() usage"
    severity: error
    languages: ["python", "javascript", "typescript"]
    rules:
      - pattern: "\\\\beval\\\\s*\\\\("
        message: "Dangerous eval() usage detected"
        remediation: "Avoid eval() - use safe alternatives"
"""
