#!/usr/bin/env python3
"""
PII Validation Extension for Novyx Sentinel
Integrates child safety PII checks with the core integrity system
"""

import json
import re
import sys
from pathlib import Path

# PII Detection Patterns (matching TypeScript version)
PII_PATTERNS = {
    'email': r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
    'phone': r'(\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b',
    'address': r'\b\d+\s+[A-Z][a-z]+\s+(Street|St|Avenue|Ave|Road|Rd|Drive|Dr|Lane|Ln|Boulevard|Blvd|Court|Ct|Way|Place|Pl)\b',
    'zipcode': r'\b\d{5}(-\d{4})?\b',
    'ssn': r'\b\d{3}-\d{2}-\d{4}\b',
}


def _redact_match(match_text: str, visible_chars: int = 4) -> str:
    """Redact a match while keeping a short suffix for identification."""
    if not match_text:
        return "<redacted>"
    suffix = match_text[-visible_chars:]
    return f"...{suffix}"


def check_pii_in_file(filepath: Path) -> dict:
    """Check a JSON file for PII violations"""
    violations = []

    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            content = f.read()
            data = json.loads(content)

        # Check all string values for PII
        def check_strings(obj, path=''):
            if isinstance(obj, dict):
                for key, value in obj.items():
                    check_strings(value, f"{path}.{key}")
            elif isinstance(obj, list):
                for i, item in enumerate(obj):
                    check_strings(item, f"{path}[{i}]")
            elif isinstance(obj, str):
                for pattern_name, pattern in PII_PATTERNS.items():
                    match = re.search(pattern, obj, re.IGNORECASE)
                    if match:
                        violations.append({
                            'path': path,
                            'type': pattern_name,
                            'file': str(filepath),
                            'redacted': _redact_match(match.group(0))
                        })

        check_strings(data)

        return {
            'file': str(filepath),
            'has_pii': len(violations) > 0,
            'violations': violations
        }

    except Exception as e:
        return {
            'file': str(filepath),
            'error': str(e)
        }


def validate_project_data(project_dir: Path) -> dict:
    """Validate all project JSON files for PII"""
    results = {
        'total_files': 0,
        'clean_files': 0,
        'files_with_pii': 0,
        'violations': []
    }
    excluded_dirs = {'node_modules', '.next', '.venv', 'dist'}

    # Check all JSON files in project directory
    for json_file in project_dir.rglob('*'):
        if json_file.suffix not in {'.json', '.jsonld'}:
            continue
        if any(part in excluded_dirs for part in json_file.parts):
            continue

        results['total_files'] += 1
        file_result = check_pii_in_file(json_file)

        if file_result.get('has_pii'):
            results['files_with_pii'] += 1
            results['violations'].extend(file_result['violations'])
        else:
            results['clean_files'] += 1

    return results


def print_report(results: dict):
    """Print PII validation report"""
    print("\n" + "="*70)
    print("🛡️  NOVYX PII VALIDATION REPORT")
    print("="*70)
    print(f"\n📊 Files Scanned: {results['total_files']}")
    print(f"✅ Clean Files: {results['clean_files']}")
    print(f"⚠️  Files with PII: {results['files_with_pii']}")

    if results['violations']:
        print("\n⚠️  PII VIOLATIONS DETECTED:\n")
        for v in results['violations']:
            print(f"   File: {v['file']}")
            print(f"   Path: {v['path']}")
            print(f"   Type: {v['type'].upper()}")
            if v.get('redacted'):
                print(f"   Match: {v['redacted']}")
            print()

    print("="*70)

    if results['files_with_pii'] > 0:
        print("❌ PII VALIDATION FAILED")
        print("   Action Required: Remove personal information before deployment")
        return 1
    else:
        print("✅ PII VALIDATION PASSED")
        print("   All files are safe for public deployment")
        return 0


if __name__ == '__main__':
    # Run from indynigo directory or specify path
    project_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else Path('.')

    print(f"🔍 Scanning for PII in: {project_dir.absolute()}")

    results = validate_project_data(project_dir)
    exit_code = print_report(results)

    sys.exit(exit_code)
