#!/usr/bin/env python3
"""
Axiom Zero — Dynamic Server Discovery & IP Failover Engine
Guarantees that frontend applications (GTK Dev Control Center & 1-Click Deployer)
always discover and auto-reconnect to the active Linux security backend server.
"""

import os
import sys
import json
import time
import urllib.request
import urllib.error
import socket
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] [Discovery] %(message)s")

class DynamicDiscovery:
    def __init__(self, primary_ip='127.0.0.1', ports=[8080, 8081, 8082, 8083]):
        self.primary_ip = primary_ip
        self.ports = ports
        self.timeout = 2.0
        
    def _create_socket(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.settimeout(self.timeout)
        return s

    def discover_and_connect(self):
        # 4-tier failover state machine
        for attempt, port in enumerate(self.ports, start=1):
            s = self._create_socket()
            try:
                logging.info(f"Tier {attempt}: Attempting connection on {self.primary_ip}:{port}")
                s.connect((self.primary_ip, port))
                logging.info(f"Tier {attempt}: Successfully connected on {self.primary_ip}:{port}")
                return s
            except socket.timeout:
                logging.warning(f"Tier {attempt}: Timeout connecting to {port}")
            except ConnectionRefusedError:
                logging.warning(f"Tier {attempt}: Connection refused on {port}")
            except Exception as e:
                logging.error(f"Tier {attempt}: Exception on {port}: {e}")
            finally:
                if s.fileno() != -1: # if not successfully returned
                    s.close()
            time.sleep(0.5)

        # IPC Fallback
        logging.warning("All 4 tiers failed. Falling back to local IPC domain sockets...")
        try:
            return self._ipc_fallback()
        except Exception as e:
            logging.critical(f"IPC Fallback also failed: {e}")
            raise RuntimeError("Complete connection failure across all tiers and IPC") from e

    def _ipc_fallback(self):
        ipc_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        ipc_socket.settimeout(self.timeout)
        ipc_socket.connect("/tmp/axiom_zero_ipc.sock")
        return ipc_socket

if __name__ == "__main__":
    discovery = DynamicDiscovery()
    try:
        sock = discovery.discover_and_connect()
        print("Successfully discovered and connected.")
        sock.close()
    except Exception as e:
        print(f"Failed to connect: {e}")
