#!/usr/bin/env python3
"""
Map all service dependencies that reference IPs that will change
Finds references in: Cloudflare configs, Nginx configs, .env files, firewall rules, DNS records
"""

import os
import re
import glob
from datetime import datetime
from collections import defaultdict

# DHCP containers and their current IPs (from inventory)
DHCP_CONTAINERS = {
    '3500': {'name': 'oracle-publisher-1', 'host': 'ml110', 'current_ip': '192.168.11.15'},
    '3501': {'name': 'ccip-monitor-1', 'host': 'ml110', 'current_ip': '192.168.11.14'},
    '100': {'name': 'proxmox-mail-gateway', 'host': 'r630-02', 'current_ip': '192.168.11.4'},
    '101': {'name': 'proxmox-datacenter-manager', 'host': 'r630-02', 'current_ip': '192.168.11.6'},
    '102': {'name': 'cloudflared', 'host': 'r630-02', 'current_ip': '192.168.11.9'},
    '103': {'name': 'omada', 'host': 'r630-02', 'current_ip': '192.168.11.20'},
    '104': {'name': 'gitea', 'host': 'r630-02', 'current_ip': '192.168.11.18'},
    '6200': {'name': 'firefly-1', 'host': 'r630-02', 'current_ip': '192.168.11.7'},
    '7811': {'name': 'mim-api-1', 'host': 'r630-02', 'current_ip': 'N/A'},
}

# IPs that will change
CHANGING_IPS = {info['current_ip'] for info in DHCP_CONTAINERS.values() if info['current_ip'] != 'N/A'}

# Also include reserved range IPs that are conflicts
CONFLICT_IPS = ['192.168.11.14', '192.168.11.15', '192.168.11.18', '192.168.11.20']

ALL_CHANGING_IPS = CHANGING_IPS | set(CONFLICT_IPS)

print("=== Mapping Service Dependencies ===")
print(f"\nIPs that will change: {sorted(ALL_CHANGING_IPS)}")
print(f"\nScanning for references...\n")

# Track dependencies
dependencies = defaultdict(list)

# Search patterns
search_patterns = [
    ('*.sh', 'Shell scripts'),
    ('*.py', 'Python scripts'),
    ('*.md', 'Documentation'),
    ('*.conf', 'Configuration files'),
    ('*.env', 'Environment files'),
    ('*.yaml', 'YAML configs'),
    ('*.yml', 'YAML configs'),
    ('*.json', 'JSON configs'),
    ('*.toml', 'TOML configs'),
]

base_dir = '/home/intlc/projects/proxmox'

# Search for IP references
for pattern, file_type in search_patterns:
    for file_path in glob.glob(os.path.join(base_dir, '**', pattern), recursive=True):
        # Skip certain directories
        if any(skip in file_path for skip in ['.git', 'node_modules', '__pycache__', '.cursor']):
            continue
        
        try:
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                content = f.read()
                lines = content.split('\n')
                
                for line_num, line in enumerate(lines, 1):
                    for ip in ALL_CHANGING_IPS:
                        if ip in line:
                            rel_path = os.path.relpath(file_path, base_dir)
                            dependencies[ip].append({
                                'file': rel_path,
                                'line': line_num,
                                'content': line.strip()[:100],
                                'type': file_type
                            })
        except Exception as e:
            continue

# Generate output
output_file = f"/home/intlc/projects/proxmox/SERVICE_DEPENDENCIES_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"

with open(output_file, 'w') as f:
    f.write(f"""# Service Dependencies - IP References

**Generated**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
**Purpose**: Map all references to IPs that will change during DHCP to static conversion

---

## IPs That Will Change

""")
    
    for ip in sorted(ALL_CHANGING_IPS):
        # Find which container uses this IP
        container_info = None
        for vmid, info in DHCP_CONTAINERS.items():
            if info['current_ip'] == ip:
                container_info = f"VMID {vmid} ({info['name']}) on {info['host']}"
                break
        
        if not container_info and ip in CONFLICT_IPS:
            container_info = "IP conflict (reserved range)"
        
        f.write(f"- **{ip}**: {container_info}\n")
    
    f.write(f"""
---

## Dependencies by IP

""")
    
    for ip in sorted(ALL_CHANGING_IPS):
        if ip not in dependencies:
            continue
        
        f.write(f"""
### {ip}

**Total References**: {len(dependencies[ip])}

| File | Line | Type | Content Preview |
|------|------|------|----------------|
""")
        
        for dep in dependencies[ip]:
            f.write(f"| `{dep['file']}` | {dep['line']} | {dep['type']} | `{dep['content']}` |\n")
    
    f.write(f"""
---

## Summary

- **Total IPs changing**: {len(ALL_CHANGING_IPS)}
- **Total references found**: {sum(len(deps) for deps in dependencies.values())}
- **Files affected**: {len(set(dep['file'] for deps in dependencies.values() for dep in deps))}

---

## Action Required

After converting DHCP containers to static IPs, update all references in the files listed above.

**Note**: Pay special attention to:
- Cloudflare tunnel configurations
- Nginx Proxy Manager routes
- Application .env files
- Firewall rules
- DNS records
""")

print(f"\n=== Dependency Mapping Complete ===")
print(f"IPs scanned: {len(ALL_CHANGING_IPS)}")
print(f"Total references found: {sum(len(deps) for deps in dependencies.values())}")
print(f"Files affected: {len(set(dep['file'] for deps in dependencies.values() for dep in deps))}")
print(f"\nOutput file: {output_file}")

# Show summary by IP
print(f"\n=== References by IP ===")
for ip in sorted(ALL_CHANGING_IPS):
    count = len(dependencies.get(ip, []))
    if count > 0:
        print(f"  {ip}: {count} reference(s)")
