#!/usr/bin/env python3
"""
Generate TinyRDM connections.yaml from sdm status --json output
Organizes Redis connections into Internal, Stage, and Production groups
Excludes activate and readonly connections
"""

import subprocess
import json
import re
import os
import yaml
from collections import defaultdict

def run_sdm_status():
    try:
        result = subprocess.run(['sdm', 'status', '--json'], capture_output=True, text=True)
        if result.returncode != 0:
            print(f"Error running sdm status: {result.stderr}")
            return None
        return json.loads(result.stdout)
    except FileNotFoundError:
        print("Error: sdm command not found")
        return None
    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}")
        return None

def parse_redis_connections(sdm_data):
    connections = []
    excluded = ['activate-cache', 'activate-readonly', 'readonly-redis']
    
    for item in sdm_data:
        if item.get('type') != 'redis':
            continue
            
        name = item.get('name', '')
        if any(x in name for x in excluded):
            continue
        
        address = item.get('address', '')
        if ':' not in address:
            continue
        
        addr, port = address.split(':')
        env_info = parse_connection_name(name)
        
        if env_info:
            connections.append({
                'name': name,
                'addr': addr,
                'port': int(port),
                **env_info
            })
    
    return connections

def parse_connection_name(name):
    pattern = r'oc-([^-]+)-([^-]+)-.*'
    match = re.match(pattern, name)
    
    if not match:
        return None
    
    environment = match.group(1)
    customer = match.group(2)
    
    if environment in ['dev', 'nextrc', 'nextrc2']:
        stage = 'internal'
    elif environment in ['stage', 'stage2', 'uat']:
        stage = 'stage'
    elif environment in ['prod', 'prod2']:
        stage = 'production'
    else:
        stage = 'unknown'
    
    return {
        'environment': environment,
        'customer': customer,
        'stage': stage
    }

def is_sdm_connection(conn_name):
    """Check if connection name matches SDM pattern (oc-*-*-*)"""
    pattern = r'oc-([^-]+)-([^-]+)-.*'
    return re.match(pattern, conn_name) is not None

def load_existing_connections(output_file):
    """Load existing connections, filtering out SDM connections"""
    if not os.path.exists(output_file):
        return {}
    
    try:
        with open(output_file, 'r') as f:
            data = yaml.safe_load(f) or []
        
        preserved_groups = {}
        
        for item in data:
            if not isinstance(item, dict):
                continue
            
            # Handle grouped connections
            if item.get("type") == "group":
                group_name = item.get("name", "")
                connections = item.get("connections", [])
                
                # Filter out SDM connections
                non_sdm_conns = []
                for conn in connections:
                    conn_name = conn.get("name", "")
                    if conn_name and not is_sdm_connection(conn_name):
                        non_sdm_conns.append(conn)
                
                if non_sdm_conns:
                    preserved_groups[group_name] = non_sdm_conns
            
            # Handle ungrouped connections (top-level connections)
            elif item.get("type") != "group" and "addr" in item and "port" in item:
                # This is a standalone connection (not in a group)
                conn_name = item.get("name", "")
                if conn_name and not is_sdm_connection(conn_name):
                    # Put ungrouped connections into a special group
                    if 'ungrouped' not in preserved_groups:
                        preserved_groups['ungrouped'] = []
                    preserved_groups['ungrouped'].append(item)
        
        return preserved_groups
    
    except Exception as e:
        print(f"⚠️  Error reading existing config: {e}")
        return {}

def create_connection_yaml(name, addr, port, stage):
    colors = {
        'internal': '#4ECF60',
        'stage': '#FFA500',
        'production': '#FF0000'
    }
    
    color = colors.get(stage, '#808080')
    
    return f"""    - name: {name}
      last_db: 0
      network: tcp
      addr: {addr}
      port: {port}
      default_filter: '*'
      key_separator: ':'
      conn_timeout: 60
      exec_timeout: 60
      db_filter_type: none
      load_size: 10000
      mark_color: '{color}'
      refresh_interval: 5"""

def group_connections(connections):
    groups = defaultdict(list)
    
    for conn in connections:
        # Group by customer (internal/features -> 'internal', otherwise by customer)
        if conn['customer'] == 'internal' or conn['customer'].startswith('feature'):
            group_name = 'internal'
        elif conn['stage'] in ['stage', 'production']:
            group_name = conn['customer']
        else:
            group_name = 'other'
        
        # Use stage directly for color coding
        conn_yaml = create_connection_yaml(
            conn['name'],
            conn['addr'],
            conn['port'],
            conn['stage']
        )
        
        groups[group_name].append(conn_yaml)
    
    return groups

def format_connection_for_yaml(conn):
    """Format a connection dict as YAML string with proper indentation"""
    yaml_str = yaml.dump(conn, default_flow_style=False, sort_keys=False)
    # Add list marker and proper indentation
    lines = yaml_str.split('\n')
    formatted_lines = []
    for i, line in enumerate(lines):
        if line.strip():
            # First line should start with "    - "
            if i == 0:
                formatted_lines.append(f"    - {line.strip()}")
            else:
                formatted_lines.append(f"      {line}")
    return '\n'.join(formatted_lines)

def generate_yaml_content(groups, preserved_connections):
    """Generate YAML content from SDM groups and preserved connections"""
    yaml_lines = []
    
    # Prefer 'internal' first, then alphabetical by customer
    ordered_groups = []
    if 'internal' in groups:
        ordered_groups.append('internal')
    ordered_groups.extend(sorted([g for g in groups.keys() if g != 'internal']))
    
    # Add preserved groups
    for group_name in preserved_connections.keys():
        if group_name not in ordered_groups:
            ordered_groups.append(group_name)
    
    for group_name in ordered_groups:
        yaml_lines.append(f"- name: {group_name}")
        yaml_lines.append("  last_db: 0")
        yaml_lines.append("  type: group")
        yaml_lines.append("  connections:")
        
        # Add connections (preserved first, then SDM)
        if group_name in preserved_connections:
            for conn_dict in preserved_connections[group_name]:
                yaml_lines.append(format_connection_for_yaml(conn_dict))
        if group_name in groups:
            for conn_yaml in groups[group_name]:
                yaml_lines.append(conn_yaml)
        
        yaml_lines.append("")
    
    return '\n'.join(yaml_lines)

def main():
    print("Generating TinyRDM connections.yaml from sdm status --json...")
    
    output_file = os.path.expanduser('~/.config/TinyRDM/connections.yaml')
    
    # Load existing connections to preserve non-SDM connections
    preserved_connections = load_existing_connections(output_file)
    preserved_count = sum(len(conns) for conns in preserved_connections.values())
    if preserved_count > 0:
        print(f"📁 Found {preserved_count} existing non-SDM connections")
    
    sdm_data = run_sdm_status()
    if not sdm_data:
        return
    
    connections = parse_redis_connections(sdm_data)
    print(f"🔍 Found {len(connections)} Redis connections from SDM")
    
    groups = group_connections(connections)
    for group_name, conns in groups.items():
        print(f"  {group_name}: {len(conns)} connections")
    
    yaml_content = generate_yaml_content(groups, preserved_connections)
    
    try:
        with open(output_file, 'w') as f:
            f.write(yaml_content)
        print(f"✅ Successfully generated {output_file}")
        if preserved_count > 0:
            print(f"💾 Preserved {preserved_count} non-SDM connections")
    except Exception as e:
        print(f"❌ Error writing file: {e}")

if __name__ == '__main__':
    main()