#!/usr/bin/env python3

import ssl
import sys
import json
import argparse
from datetime import datetime

try:
    from librouteros import connect
    from librouteros.query import Key
except ImportError:
    print("Error: librouteros module not found")
    print("Install with: pip install librouteros")
    sys.exit(1)

def get_router_data(host, username='grahamro', password='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', port=8729):
    """
    Connect to a MikroTik router and retrieve network configuration
    
    Args:
        host: IP address or hostname of the router
        username: Router username (default: grahamro)
        password: Router password
        port: API-SSL port (default: 8729)
    
    Returns:
        Dictionary containing router configuration data
    """
    
    print(f"=== Connecting to MikroTik Router ({host}) ===\n")
    
    # SSL context for secure connection
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    
    try:
        # Connect to router
        api = connect(
            username=username,
            password=password,
            host=host,
            port=port,
            ssl_wrapper=ctx.wrap_socket
        )
        
        print("✓ Connected successfully\n")
        
        # Get router identity
        identity = None
        try:
            identity_data = api('/system/identity/print')
            if identity_data:
                identity = identity_data[0].get('name', 'Unknown')
                print(f"Router Identity: {identity}\n")
        except:
            print("Could not retrieve router identity\n")
        
        # Get IP addresses
        print("=== IP Addresses ===")
        ip_addresses = api('/ip/address/print')
        
        subnets = []
        for addr in ip_addresses:
            if not addr.get('disabled', False):
                address = addr['address']
                interface = addr.get('interface', 'unknown')
                network = addr.get('network', '')
                comment = addr.get('comment', '')
                dynamic = addr.get('dynamic', False)
                
                print(f"Interface: {interface}")
                print(f"  Address: {address}")
                print(f"  Network: {network}")
                if comment:
                    print(f"  Comment: {comment}")
                if dynamic:
                    print(f"  Dynamic: Yes")
                print()
                
                subnets.append({
                    'address': address,
                    'network': network,
                    'interface': interface,
                    'comment': comment,
                    'dynamic': dynamic
                })
        
        # Get interfaces
        print("\n=== Active Interfaces ===")
        interfaces = api('/interface/print')
        active_interfaces = []
        
        for iface in interfaces:
            if not iface.get('disabled', False) and iface.get('running', False):
                name = iface['name']
                itype = iface.get('type', 'unknown')
                mac = iface.get('mac-address', 'N/A')
                comment = iface.get('comment', '')
                mtu = iface.get('mtu', 'default')
                
                active_interfaces.append({
                    'name': name,
                    'type': itype,
                    'mac': mac,
                    'comment': comment,
                    'mtu': mtu
                })
                
                print(f"{name} ({itype})")
                if comment:
                    print(f"  Comment: {comment}")
                if mac != 'N/A':
                    print(f"  MAC: {mac}")
        
        # Get VLANs
        print("\n\n=== VLANs ===")
        vlans = []
        try:
            vlan_interfaces = api('/interface/vlan/print')
            for vlan in vlan_interfaces:
                if not vlan.get('disabled', False):
                    name = vlan['name']
                    vlan_id = vlan.get('vlan-id', 'unknown')
                    interface = vlan.get('interface', 'unknown')
                    
                    vlans.append({
                        'name': name,
                        'vlan_id': vlan_id,
                        'interface': interface
                    })
                    
                    print(f"{name}: VLAN {vlan_id} on {interface}")
        except:
            print("No VLANs found or access denied")
        
        # Get PPPoE servers
        print("\n\n=== PPPoE Servers ===")
        pppoe_servers = []
        try:
            servers = api('/interface/pppoe-server/server/print')
            for server in servers:
                if not server.get('disabled', False):
                    name = server.get('service-name', 'unnamed')
                    interface = server.get('interface', 'unknown')
                    
                    pppoe_servers.append({
                        'service_name': name,
                        'interface': interface
                    })
                    
                    print(f"Service: {name} on {interface}")
        except:
            print("No PPPoE servers found or access denied")
        
        # Get static routes
        print("\n\n=== Static Routes ===")
        routes = []
        try:
            static_routes = api('/ip/route/print')
            for route in static_routes:
                if not route.get('dynamic', False) and not route.get('disabled', False):
                    dst = route.get('dst-address', '')
                    gateway = route.get('gateway', '')
                    distance = route.get('distance', '')
                    comment = route.get('comment', '')
                    
                    if dst != '0.0.0.0/0':  # Skip default route for brevity
                        routes.append({
                            'destination': dst,
                            'gateway': gateway,
                            'distance': distance,
                            'comment': comment
                        })
                        
                        print(f"{dst} via {gateway}")
                        if comment:
                            print(f"  Comment: {comment}")
        except:
            print("Could not retrieve routes")
        
        # Close connection
        api.close()
        
        # Compile all data
        router_data = {
            'host': host,
            'identity': identity,
            'timestamp': datetime.now().isoformat(),
            'subnets': subnets,
            'interfaces': active_interfaces,
            'vlans': vlans,
            'pppoe_servers': pppoe_servers,
            'routes': routes
        }
        
        print(f"\n\n=== Summary ===")
        print(f"Router: {identity or host}")
        print(f"Found {len(subnets)} IP addresses/subnets")
        print(f"Found {len(active_interfaces)} active interfaces")
        print(f"Found {len(vlans)} VLANs")
        print(f"Found {len(pppoe_servers)} PPPoE servers")
        print(f"Found {len(routes)} static routes")
        
        return router_data
        
    except Exception as e:
        print(f"✗ Connection failed: {e}")
        return None


def save_router_data(data, filename=None):
    """Save router data to a JSON file"""
    if not filename:
        # Generate filename based on router identity or IP
        identity = data.get('identity') or data.get('host', 'router')
        identity_clean = identity.replace(' ', '_').replace('/', '_').replace('.', '_')
        filename = f"router_data_{identity_clean}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
    
    with open(filename, 'w') as f:
        json.dump(data, f, indent=2)
    
    print(f"\nData saved to: {filename}")
    return filename


def main():
    parser = argparse.ArgumentParser(description='Retrieve configuration from a MikroTik router')
    parser.add_argument('host', help='IP address or hostname of the router')
    parser.add_argument('--username', '-u', default='grahamro', help='Router username (default: grahamro)')
    parser.add_argument('--password', '-p', default='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', help='Router password')
    parser.add_argument('--port', type=int, default=8729, help='API-SSL port (default: 8729)')
    parser.add_argument('--output', '-o', help='Output filename (default: auto-generated)')
    parser.add_argument('--json', action='store_true', help='Output raw JSON to stdout')
    
    args = parser.parse_args()
    
    # Get router data
    data = get_router_data(args.host, args.username, args.password, args.port)
    
    if data:
        if args.json:
            # Output JSON to stdout
            print("\n=== JSON Output ===")
            print(json.dumps(data, indent=2))
        else:
            # Save to file
            save_router_data(data, args.output)
            print("\n✓ Router data retrieved successfully")
    else:
        print("\n✗ Failed to retrieve router data")
        return 1
    
    return 0


if __name__ == "__main__":
    sys.exit(main())