#!/usr/bin/env python3

import ssl
import sys
import argparse
from datetime import datetime

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

def get_router_config(host, username='grahamro', password='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', port=8729):
    """
    Get full router configuration export
    
    Args:
        host: IP address or hostname of the router
        username: Router username
        password: Router password
        port: API-SSL port (default: 8729)
    
    Returns:
        Configuration export string
    """
    
    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")
        print("Exporting configuration...")
        
        # Get router identity first
        try:
            identity_data = api('/system/identity/print')
            if identity_data:
                identity = identity_data[0].get('name', 'router')
                print(f"Router identity: {identity}")
        except:
            identity = 'router'
        
        # Export configuration
        # Note: /export returns the config in a specific format
        try:
            # For RouterOS API, we need to get specific sections
            config_sections = []
            
            # Get IP addresses
            print("\nGetting IP configuration...")
            ip_addresses = api('/ip/address/print')
            
            # Get IP pools
            print("Getting IP pools...")
            try:
                ip_pools = api('/ip/pool/print')
            except:
                ip_pools = []
            
            # Get PPPoE servers
            print("Getting PPPoE servers...")
            try:
                pppoe_servers = api('/interface/pppoe-server/server/print')
            except:
                pppoe_servers = []
                
            # Get PPP profiles
            print("Getting PPP profiles...")
            try:
                ppp_profiles = api('/ppp/profile/print')
            except:
                ppp_profiles = []
            
            # Get firewall NAT rules
            print("Getting NAT rules...")
            try:
                nat_rules = api('/ip/firewall/nat/print')
            except:
                nat_rules = []
            
            # Get DHCP servers
            print("Getting DHCP configuration...")
            try:
                dhcp_servers = api('/ip/dhcp-server/print')
                dhcp_networks = api('/ip/dhcp-server/network/print')
            except:
                dhcp_servers = []
                dhcp_networks = []
            
            # Build configuration summary
            config = f"# Configuration for {identity} ({host})\n"
            config += f"# Exported on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
            
            # IP Addresses
            config += "# IP Addresses\n"
            for addr in ip_addresses:
                if not addr.get('disabled', False) and not addr.get('dynamic', False):
                    config += f"/ip address add address={addr['address']} interface={addr.get('interface', '')} "
                    if addr.get('comment'):
                        config += f"comment=\"{addr['comment']}\""
                    config += "\n"
            
            # IP Pools
            if ip_pools:
                config += "\n# IP Pools\n"
                for pool in ip_pools:
                    config += f"/ip pool add name={pool['name']} ranges={pool.get('ranges', '')}\n"
            
            # PPPoE configuration
            if pppoe_servers:
                config += "\n# PPPoE Servers\n"
                for server in pppoe_servers:
                    if not server.get('disabled', False):
                        config += f"/interface pppoe-server server add name={server.get('service-name', '')} "
                        config += f"interface={server.get('interface', '')} "
                        if server.get('default-profile'):
                            config += f"default-profile={server['default-profile']} "
                        config += "\n"
            
            # PPP Profiles
            if ppp_profiles:
                config += "\n# PPP Profiles\n"
                for profile in ppp_profiles:
                    if profile['name'] != 'default' and profile['name'] != 'default-encryption':
                        config += f"/ppp profile add name={profile['name']} "
                        if profile.get('local-address'):
                            config += f"local-address={profile['local-address']} "
                        if profile.get('remote-address'):
                            config += f"remote-address={profile['remote-address']} "
                        config += "\n"
            
            # NAT rules
            if nat_rules:
                config += "\n# NAT Rules\n"
                for rule in nat_rules:
                    if not rule.get('disabled', False):
                        config += f"/ip firewall nat add chain={rule.get('chain', '')} "
                        if rule.get('src-address'):
                            config += f"src-address={rule['src-address']} "
                        if rule.get('dst-address'):
                            config += f"dst-address={rule['dst-address']} "
                        if rule.get('action'):
                            config += f"action={rule['action']} "
                        if rule.get('to-addresses'):
                            config += f"to-addresses={rule['to-addresses']} "
                        config += "\n"
            
            # Close connection
            api.close()
            
            return config
            
        except Exception as e:
            print(f"Error getting configuration: {e}")
            api.close()
            return None
        
    except Exception as e:
        print(f"✗ Connection failed: {e}")
        return None


def main():
    parser = argparse.ArgumentParser(description='Export 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')
    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')
    
    args = parser.parse_args()
    
    # Get router config
    config = get_router_config(args.host, args.username, args.password, args.port)
    
    if config:
        if args.output:
            with open(args.output, 'w') as f:
                f.write(config)
            print(f"\n✓ Configuration exported to: {args.output}")
        else:
            print("\n=== Configuration Export ===")
            print(config)
        
        return 0
    else:
        print("\n✗ Failed to export configuration")
        return 1


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