#!/usr/bin/env python3
"""
NEOG System - Real System Metrics Server
Coleta métricas reais do sistema e expõe via API REST
"""

from flask import Flask, jsonify
from flask_cors import CORS
import psutil
import os
import time
from datetime import datetime
import socket

app = Flask(__name__)
CORS(app)  # Permitir acesso de qualquer origem

# Porta do servidor
PORT = 3004

# Tempo de início do servidor
START_TIME = time.time()

@app.route('/health', methods=['GET'])
def health():
    """Health check endpoint"""
    return jsonify({
        'status': 'healthy',
        'service': 'system-metrics-server',
        'timestamp': datetime.now().isoformat()
    })

@app.route('/api/metrics/cpu', methods=['GET'])
def get_cpu_metrics():
    """Retorna métricas de CPU"""
    try:
        cpu_percent = psutil.cpu_percent(interval=1)
        cpu_count = psutil.cpu_count()
        cpu_freq = psutil.cpu_freq()

        # Temperatura (se disponível)
        temps = {}
        try:
            temps_dict = psutil.sensors_temperatures()
            if temps_dict:
                for name, entries in temps_dict.items():
                    temps[name] = [{'label': entry.label, 'current': entry.current} for entry in entries]
        except:
            temps = None

        return jsonify({
            'success': True,
            'data': {
                'percent': cpu_percent,
                'count': cpu_count,
                'physical_cores': psutil.cpu_count(logical=False),
                'frequency': {
                    'current': cpu_freq.current if cpu_freq else 0,
                    'min': cpu_freq.min if cpu_freq else 0,
                    'max': cpu_freq.max if cpu_freq else 0
                } if cpu_freq else None,
                'per_cpu': psutil.cpu_percent(interval=1, percpu=True),
                'temperatures': temps,
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/memory', methods=['GET'])
def get_memory_metrics():
    """Retorna métricas de memória"""
    try:
        mem = psutil.virtual_memory()
        swap = psutil.swap_memory()

        return jsonify({
            'success': True,
            'data': {
                'total': mem.total,
                'available': mem.available,
                'used': mem.used,
                'free': mem.free,
                'percent': mem.percent,
                'swap': {
                    'total': swap.total,
                    'used': swap.used,
                    'free': swap.free,
                    'percent': swap.percent
                },
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/disk', methods=['GET'])
def get_disk_metrics():
    """Retorna métricas de disco"""
    try:
        disk = psutil.disk_usage('/')
        io = psutil.disk_io_counters()

        partitions = []
        for partition in psutil.disk_partitions():
            try:
                usage = psutil.disk_usage(partition.mountpoint)
                partitions.append({
                    'device': partition.device,
                    'mountpoint': partition.mountpoint,
                    'fstype': partition.fstype,
                    'total': usage.total,
                    'used': usage.used,
                    'free': usage.free,
                    'percent': usage.percent
                })
            except:
                continue

        return jsonify({
            'success': True,
            'data': {
                'root': {
                    'total': disk.total,
                    'used': disk.used,
                    'free': disk.free,
                    'percent': disk.percent
                },
                'io': {
                    'read_count': io.read_count,
                    'write_count': io.write_count,
                    'read_bytes': io.read_bytes,
                    'write_bytes': io.write_bytes,
                    'read_time': io.read_time,
                    'write_time': io.write_time
                } if io else None,
                'partitions': partitions,
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/network', methods=['GET'])
def get_network_metrics():
    """Retorna métricas de rede"""
    try:
        net_io = psutil.net_io_counters()

        # Tentar obter conexões (requer privilégios no macOS)
        try:
            connections = len(psutil.net_connections())
        except (psutil.AccessDenied, PermissionError):
            # Fallback: estimar conexões baseado em processos ativos
            connections = len([p for p in psutil.process_iter(['connections'])
                             if p.info.get('connections')])
            if connections == 0:
                connections = -1  # Indica que não foi possível obter

        # Interfaces de rede
        interfaces = {}
        net_if_addrs = psutil.net_if_addrs()
        net_if_stats = psutil.net_if_stats()

        for interface, addrs in net_if_addrs.items():
            interfaces[interface] = {
                'addresses': [{'family': addr.family.name, 'address': addr.address} for addr in addrs],
                'is_up': net_if_stats[interface].isup if interface in net_if_stats else False
            }

        return jsonify({
            'success': True,
            'data': {
                'bytes_sent': net_io.bytes_sent,
                'bytes_recv': net_io.bytes_recv,
                'packets_sent': net_io.packets_sent,
                'packets_recv': net_io.packets_recv,
                'errors_in': net_io.errin,
                'errors_out': net_io.errout,
                'drops_in': net_io.dropin,
                'drops_out': net_io.dropout,
                'connections': connections,
                'interfaces': interfaces,
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/processes', methods=['GET'])
def get_processes():
    """Retorna lista de processos em execução"""
    try:
        processes = []

        for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'memory_percent', 'status']):
            try:
                pinfo = proc.info

                # Pegar valores com defaults se forem None
                cpu_pct = pinfo['cpu_percent'] if pinfo['cpu_percent'] is not None else 0.0
                mem_pct = pinfo['memory_percent'] if pinfo['memory_percent'] is not None else 0.0

                # Filtrar apenas processos relevantes do NEOG ou com uso significativo
                if 'python' in pinfo['name'].lower() or \
                   'node' in pinfo['name'].lower() or \
                   'ngrok' in pinfo['name'].lower() or \
                   cpu_pct > 1.0 or \
                   mem_pct > 1.0:

                    processes.append({
                        'pid': pinfo['pid'],
                        'name': pinfo['name'],
                        'username': pinfo['username'] if pinfo['username'] else 'unknown',
                        'cpu_percent': round(cpu_pct, 2),
                        'memory_percent': round(mem_pct, 2),
                        'status': pinfo['status'] if pinfo['status'] else 'unknown'
                    })
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue

        # Ordenar por uso de CPU (decrescente)
        processes.sort(key=lambda x: x['cpu_percent'], reverse=True)

        return jsonify({
            'success': True,
            'count': len(processes),
            'data': processes[:50],  # Limitar a 50 processos
            'timestamp': datetime.now().isoformat()
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/system', methods=['GET'])
def get_system_info():
    """Retorna informações gerais do sistema"""
    try:
        boot_time = datetime.fromtimestamp(psutil.boot_time())
        uptime_seconds = time.time() - psutil.boot_time()

        return jsonify({
            'success': True,
            'data': {
                'hostname': socket.gethostname(),
                'platform': os.uname().sysname,
                'release': os.uname().release,
                'version': os.uname().version,
                'machine': os.uname().machine,
                'processor': os.uname().machine,
                'boot_time': boot_time.isoformat(),
                'uptime_seconds': int(uptime_seconds),
                'users': [{'name': user.name, 'terminal': user.terminal, 'host': user.host}
                         for user in psutil.users()],
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/metrics/all', methods=['GET'])
def get_all_metrics():
    """Retorna todas as métricas de uma vez"""
    try:
        cpu = psutil.cpu_percent(interval=1)
        mem = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        net = psutil.net_io_counters()

        return jsonify({
            'success': True,
            'data': {
                'cpu': {
                    'percent': cpu,
                    'count': psutil.cpu_count()
                },
                'memory': {
                    'total': mem.total,
                    'used': mem.used,
                    'percent': mem.percent
                },
                'disk': {
                    'total': disk.total,
                    'used': disk.used,
                    'percent': disk.percent
                },
                'network': {
                    'bytes_sent': net.bytes_sent,
                    'bytes_recv': net.bytes_recv
                },
                'timestamp': datetime.now().isoformat()
            }
        })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/', methods=['GET'])
def index():
    """Documentação da API"""
    return jsonify({
        'service': 'NEOG System Metrics Server',
        'version': '1.0',
        'description': 'API REST para métricas reais do sistema',
        'endpoints': {
            'health': {
                'method': 'GET',
                'path': '/health',
                'description': 'Health check'
            },
            'cpu': {
                'method': 'GET',
                'path': '/api/metrics/cpu',
                'description': 'Métricas de CPU'
            },
            'memory': {
                'method': 'GET',
                'path': '/api/metrics/memory',
                'description': 'Métricas de memória'
            },
            'disk': {
                'method': 'GET',
                'path': '/api/metrics/disk',
                'description': 'Métricas de disco'
            },
            'network': {
                'method': 'GET',
                'path': '/api/metrics/network',
                'description': 'Métricas de rede'
            },
            'processes': {
                'method': 'GET',
                'path': '/api/metrics/processes',
                'description': 'Processos em execução'
            },
            'system': {
                'method': 'GET',
                'path': '/api/metrics/system',
                'description': 'Informações do sistema'
            },
            'all': {
                'method': 'GET',
                'path': '/api/metrics/all',
                'description': 'Todas as métricas (resumo)'
            }
        }
    })

if __name__ == '__main__':
    print('')
    print('╔═══════════════════════════════════════════════════════════╗')
    print('║                                                           ║')
    print('║     📊 NEOG SYSTEM METRICS SERVER - v1.0 📊             ║')
    print('║                                                           ║')
    print('╚═══════════════════════════════════════════════════════════╝')
    print('')
    print(f'✅ Servidor rodando em: http://localhost:{PORT}')
    print('')
    print('🔗 Endpoints disponíveis:')
    print(f'   GET /api/metrics/cpu        - Métricas de CPU')
    print(f'   GET /api/metrics/memory     - Métricas de memória')
    print(f'   GET /api/metrics/disk       - Métricas de disco')
    print(f'   GET /api/metrics/network    - Métricas de rede')
    print(f'   GET /api/metrics/processes  - Processos rodando')
    print(f'   GET /api/metrics/system     - Info do sistema')
    print(f'   GET /api/metrics/all        - Todas as métricas')
    print(f'   GET /health                 - Health check')
    print('')
    print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
    print('')

    app.run(host='0.0.0.0', port=PORT, debug=False)
