"""Privacy content filtering for ingestion."""

from __future__ import annotations

import fnmatch
import re

from neurovault.config import NeurovaultConfig


class ContentFilter:
    """Multi-layer content filtering for privacy."""

    SENSITIVE_PATTERNS = [
        (r"(?i)(password|passwd|pwd|secret)\s*[:=]\s*\S+", "credential"),
        (r"(?i)(api[_-]?key|auth[_-]?token|access[_-]?token)\s*[:=]\s*\S+", "api_key"),
        (r"AKIA[0-9A-Z]{16}", "aws_key"),
        (r"sk-[a-zA-Z0-9]{20,}", "openai_key"),
        (r"ghp_[a-zA-Z0-9]{36}", "github_pat"),
        (r"gho_[a-zA-Z0-9]{36}", "github_oauth"),
        (r"xox[baprs]-[a-zA-Z0-9-]+", "slack_token"),
        (r"\b\d{3}-\d{2}-\d{4}\b", "ssn"),
        (r"\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b", "credit_card"),
        (r"\b[A-Z]{2}\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}\b", "iban"),
        (r"-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----", "private_key"),
        (r"-----BEGIN\s+OPENSSH\s+PRIVATE\s+KEY-----", "ssh_key"),
    ]

    def __init__(self, config: NeurovaultConfig):
        self._config = config
        self._compiled = [(re.compile(p), label) for p, label in self.SENSITIVE_PATTERNS]
        self._custom_patterns = [
            re.compile(p) for p in config.privacy.get("content_blocklist", [])
        ]

    def filter(self, content: str, source: str) -> tuple[str | None, str]:
        """
        Filter content for privacy.
        Returns: (filtered_content or None if blocked, reason)
        """
        if source.startswith("browser"):
            url = self._extract_url(content)
            if url and self._is_url_blocked(url):
                return None, "blocked_url"

        for pattern, label in self._compiled:
            if pattern.search(content):
                content = pattern.sub(f"[REDACTED:{label}]", content)

        for pattern in self._custom_patterns:
            if pattern.search(content):
                return None, "custom_blocklist"

        if len(content) > 50000:
            content = content[:50000] + "\n... [truncated]"

        return content, "passed"

    @staticmethod
    def _extract_url(content: str) -> str:
        for line in content.splitlines():
            line = line.strip()
            if line.lower().startswith("url:"):
                return line.split(":", 1)[1].strip()
            if line.startswith(("http://", "https://")):
                return line
        return ""

    def _is_url_blocked(self, url: str) -> bool:
        for pattern in self._config.privacy.get("url_blocklist", []):
            if fnmatch.fnmatch(url, pattern):
                return True
        return False
