#!/usr/bin/python3

import os
import sys
import json
import csv
import urllib.parse

# Add the apps directory to the Python path
sys.path.insert(0, '/opt/ngon/apps')

print("Content-Type: application/json\n")

def parse_position(position_str):
    """Parse position string like '1-7-01' into (pod, row, pos)"""
    if not position_str or position_str.strip() == '':
        return None, None, None
    
    parts = position_str.split('-')
    if len(parts) == 3:
        try:
            return int(parts[0]), int(parts[1]), int(parts[2])
        except ValueError:
            return None, None, None
    return None, None, None

def load_inventory(pod_name):
    """Load inventory data for the specified pod"""
    inventory = {}
    try:
        with open('/opt/ngon/data/live/miner_inventory.csv', 'r') as f:
            reader = csv.DictReader(f)
            for row in reader:
                site = row['Site'].strip()
                pod_num = row['Pod'].strip()
                
                if pod_num:
                    full_pod_name = f"{site} {pod_num}"
                else:
                    full_pod_name = site
                
                matches_pod = (
                    full_pod_name.lower() == pod_name.strip().lower() or
                    site.lower() == pod_name.strip().lower()
                )
                
                if matches_pod:
                    position = row['Position']
                    pod_idx, row_num, pos_num = parse_position(position)
                    
                    if pod_idx is not None and row_num is not None and pos_num is not None:
                        if row_num not in inventory:
                            inventory[row_num] = {}
                        
                        serial = row['Serial'].strip() if row['Serial'] else ''
                        mac = row['MAC'].strip() if row['MAC'] else ''
                        is_empty = not serial and not mac
                        
                        inventory[row_num][pos_num] = {
                            'serial': serial,
                            'mac': mac,
                            'installed': not is_empty
                        }
    except Exception as e:
        pass
    
    return inventory

def load_miners(pod_name):
    """Load miner data for the specified pod"""
    miners = {}
    try:
        with open('/opt/ngon/data/live/miner_status.csv', 'r') as f:
            reader = csv.DictReader(f)
            for row in reader:
                if row['pod'].strip().lower() == pod_name.strip().lower():
                    position = row['position']
                    pod_idx, row_num, pos_num = parse_position(position)
                    
                    if pod_idx is not None and row_num is not None and pos_num is not None:
                        if row_num not in miners:
                            miners[row_num] = {}
                        
                        miners[row_num][pos_num] = {
                            'mac': row['mac'],
                            'hashrate': float(row['hs_rt']) if row['hs_rt'] else 0,
                            'power': float(row['power']) if row['power'] else 0,
                            'error_codes': row['error_codes'],
                            'miner_type': row['miner_type'],
                            'uptime': row['uptime']
                        }
    except Exception as e:
        pass
    
    return miners

def load_sleeping_miners():
    """Load sleeping miners from miner_status.csv based on mining_state column"""
    sleeping_miners = set()
    try:
        with open('/opt/ngon/data/live/miner_status.csv', 'r') as f:
            reader = csv.DictReader(f)
            for row in reader:
                mining_state = row.get('mining_state', '').strip().lower()
                if mining_state == 'sleeping':
                    mac = row.get('mac', '').strip().lower()
                    if mac:
                        sleeping_miners.add(mac)
    except (FileNotFoundError, Exception):
        pass
    return sleeping_miners

def get_miner_color(row_num, pos_num, inventory, miners, sleeping_miners, miner_type_specs=None):
    """Determine color for a miner square based on inventory and miner data"""
    has_inventory = row_num in inventory and pos_num in inventory[row_num]
    inventory_entry = inventory[row_num][pos_num] if has_inventory else None
    
    if not has_inventory or not inventory_entry['installed']:
        return 'empty'
    
    has_miner_data = row_num in miners and pos_num in miners[row_num]
    miner_data = miners[row_num][pos_num] if has_miner_data else None
    
    if not has_miner_data:
        return 'offline'
    
    hashrate = miner_data['hashrate']
    has_errors = bool(miner_data['error_codes'] and miner_data['error_codes'].strip())
    miner_type = miner_data['miner_type']
    mac = miner_data['mac'].lower()
    
    # Check if miner is sleeping first
    if mac in sleeping_miners:
        return 'sleeping'

    # If not sleeping, determine color based on hashrate
    if hashrate == 0:
        base_color = 'zero-hash'
    else:
        # Use simple thresholds for mobile view
        if 'whatsminer' in miner_type.lower():
            good_threshold = 150
        elif 'antminer' in miner_type.lower() or 'jpro' in miner_type.lower():
            good_threshold = 90
        else:
            good_threshold = 150

        if hashrate >= good_threshold:
            base_color = 'hashing'
        else:
            base_color = 'low-hash'

    return base_color

def generate_sitemap_data(pod_name):
    """Generate sitemap data for a pod"""
    inventory = load_inventory(pod_name)
    miners = load_miners(pod_name)
    sleeping_miners = load_sleeping_miners()
    
    if not inventory and not miners:
        return {"error": "No data found for this pod"}
    
    # Find all rows and positions
    all_rows = set()
    all_positions = set()
    
    for row_num in inventory:
        all_rows.add(row_num)
        for pos_num in inventory[row_num]:
            all_positions.add(pos_num)
    
    for row_num in miners:
        all_rows.add(row_num)
        for pos_num in miners[row_num]:
            all_positions.add(pos_num)
    
    if not all_rows or not all_positions:
        return {"error": "No positions found for this pod"}
    
    min_row, max_row = min(all_rows), max(all_rows)
    min_pos, max_pos = min(all_positions), max(all_positions)
    
    # Calculate statistics
    stats = {
        'total_slots': 0,
        'installed_count': 0,
        'online_count': 0,
        'hashing_count': 0,
        'sleeping_count': 0,
        'low_hash_count': 0,
        'zero_hash_count': 0
    }
    
    grid_data = []
    
    for row in range(min_row, max_row + 1):
        row_data = []
        for pos in range(min_pos, max_pos + 1):
            has_inventory = row in inventory and pos in inventory[row]
            has_miner_data = row in miners and pos in miners[row]
            
            if has_inventory:
                stats['total_slots'] += 1
                if inventory[row][pos]['installed']:
                    stats['installed_count'] += 1
                    if has_miner_data:
                        stats['online_count'] += 1
                        mac = miners[row][pos]['mac'].lower()
                        hashrate = miners[row][pos]['hashrate']
                        
                        if mac in sleeping_miners:
                            stats['sleeping_count'] += 1
                        elif hashrate == 0:
                            stats['zero_hash_count'] += 1
                        elif hashrate >= 90:  # Simple threshold
                            stats['hashing_count'] += 1
                        else:
                            stats['low_hash_count'] += 1
            
            color = get_miner_color(row, pos, inventory, miners, sleeping_miners)
            
            # Get display info
            position_display = f"{row:02d}-{pos:02d}" if color != 'empty' else ""
            mac_display = ""
            
            if color != 'empty' and has_miner_data:
                mac = miners[row][pos]['mac']
                mac_display = mac[-5:].replace(':', '').upper()
            elif color != 'empty' and has_inventory:
                mac = inventory[row][pos]['mac']
                mac_display = mac[-5:].replace(':', '').upper() if mac else ""
            
            # Add miner details if available
            miner_details = {}
            if has_miner_data:
                miner_details = {
                    'mac': miners[row][pos]['mac'],
                    'hashrate': miners[row][pos]['hashrate'],
                    'power': miners[row][pos]['power'],
                    'error_codes': miners[row][pos]['error_codes'],
                    'miner_type': miners[row][pos]['miner_type'],
                    'uptime': miners[row][pos]['uptime']
                }
            
            row_data.append({
                'row': row,
                'pos': pos,
                'color': color,
                'position_display': position_display,
                'mac_display': mac_display,
                'miner_details': miner_details
            })
        
        grid_data.append(row_data)
    
    return {
        'pod_name': pod_name,
        'grid_data': grid_data,
        'stats': stats,
        'dimensions': {
            'min_row': min_row,
            'max_row': max_row,
            'min_pos': min_pos,
            'max_pos': max_pos
        }
    }

# Main execution
try:
    query_string = os.environ.get('QUERY_STRING', '')
    params = urllib.parse.parse_qs(query_string)
    pod_name = params.get('pod', [''])[0]
    
    if not pod_name:
        data = {"error": "Missing pod parameter"}
    else:
        data = generate_sitemap_data(pod_name)
    
    print(json.dumps(data, indent=2))
    
except Exception as e:
    print(json.dumps({"error": str(e)}, indent=2))