#!/usr/bin/env python3

import os
import requests
import json
from urllib.parse import urljoin

class NetBoxManager:
    def __init__(self, url, token):
        self.base_url = url.rstrip('/')
        self.api_url = urljoin(self.base_url + '/', 'api/')
        self.headers = {
            'Authorization': f'Token {token}',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }
        self.session = requests.Session()
        self.session.headers.update(self.headers)
    
    def get(self, endpoint, params=None):
        """Make GET request to NetBox API"""
        url = urljoin(self.api_url, endpoint.lstrip('/'))
        response = self.session.get(url, params=params)
        response.raise_for_status()
        return response.json()
    
    def post(self, endpoint, data):
        """Make POST request to NetBox API"""
        url = urljoin(self.api_url, endpoint.lstrip('/'))
        response = self.session.post(url, json=data)
        if response.status_code not in [200, 201]:
            print(f"Error creating {endpoint}: {response.status_code}")
            print(f"Response: {response.text}")
        response.raise_for_status()
        return response.json()
    
    def create_site(self, name, slug=None, status='active', comments=''):
        """Create a new site"""
        if not slug:
            slug = name.lower().replace(' ', '-')
        
        site_data = {
            'name': name,
            'slug': slug,
            'status': status,
            'comments': comments
        }
        
        return self.post('dcim/sites/', site_data)
    
    def create_device(self, name, device_type_id, role_id, site_id, status='active'):
        """Create a new device"""
        device_data = {
            'name': name,
            'device_type': device_type_id,
            'role': role_id,
            'site': site_id,
            'status': status
        }
        
        return self.post('dcim/devices/', device_data)
    
    def get_or_create_manufacturer(self, name):
        """Get or create a manufacturer"""
        response = self.get('dcim/manufacturers/', params={'name': name})
        if response['count'] > 0:
            return response['results'][0]['id']
        
        # Create manufacturer
        mfg_data = {
            'name': name,
            'slug': name.lower()
        }
        created = self.post('dcim/manufacturers/', mfg_data)
        return created['id']
    
    def get_or_create_device_type(self, model, manufacturer_id):
        """Get or create a device type"""
        response = self.get('dcim/device-types/', params={'model': model})
        if response['count'] > 0:
            return response['results'][0]['id']
        
        # Create device type
        dt_data = {
            'manufacturer': manufacturer_id,
            'model': model,
            'slug': model.lower().replace(' ', '-').replace('/', '-')
        }
        created = self.post('dcim/device-types/', dt_data)
        return created['id']
    
    def get_or_create_device_role(self, name, slug=None):
        """Get or create a device role"""
        if not slug:
            slug = name.lower().replace(' ', '-')
            
        response = self.get('dcim/device-roles/', params={'name': name})
        if response['count'] > 0:
            return response['results'][0]['id']
        
        # Create device role
        role_data = {
            'name': name,
            'slug': slug,
            'color': '2196f3'  # Blue color
        }
        created = self.post('dcim/device-roles/', role_data)
        return created['id']


def main():
    # Get API token from environment variable or use the one from CLAUDE.md
    api_token = os.environ.get('NETBOX_KEY', 'e50298f7fd20f7fd6f1931f635511b34f6e8cfde')
    
    # Initialize NetBox client
    nb = NetBoxManager('https://netbox.vntx.net/', api_token)
    
    print("=== Creating Verona Site and Router in NetBox ===\n")
    
    # Check if Verona site exists
    site_response = nb.get('dcim/sites/', params={'name': 'Verona'})
    
    if site_response['count'] == 0:
        # Create Verona site
        print("Creating Verona site...")
        try:
            site = nb.create_site(
                name='Verona',
                slug='verona',
                status='active',
                comments='Verona tower site with MikroTik router'
            )
            site_id = site['id']
            print(f"✓ Created Verona site (ID: {site_id})")
        except Exception as e:
            print(f"✗ Failed to create Verona site: {e}")
            return
    else:
        site_id = site_response['results'][0]['id']
        print(f"✓ Verona site already exists (ID: {site_id})")
    
    # Check if router already exists
    device_response = nb.get('dcim/devices/', params={'name': 'verona-router', 'site_id': site_id})
    
    if device_response['count'] == 0:
        print("\nCreating Verona router device...")
        
        # Get or create MikroTik manufacturer
        print("  - Setting up manufacturer...")
        manufacturer_id = nb.get_or_create_manufacturer('MikroTik')
        
        # Get or create device type (assuming RouterBOARD or generic)
        print("  - Setting up device type...")
        device_type_id = nb.get_or_create_device_type('RouterBOARD', manufacturer_id)
        
        # Get or create device role
        print("  - Setting up device role...")
        role_id = nb.get_or_create_device_role('Router')
        
        # Create the device
        try:
            device = nb.create_device(
                name='verona-router',
                device_type_id=device_type_id,
                role_id=role_id,
                site_id=site_id,
                status='active'
            )
            device_id = device['id']
            print(f"✓ Created Verona router device (ID: {device_id})")
            
            # Add primary IP
            print("\n  - Adding primary IP address...")
            ip_data = {
                'address': '10.254.254.101/32',
                'status': 'active',
                'description': 'Verona router loopback',
                'role': 'loopback'
            }
            try:
                ip_response = nb.post('ipam/ip-addresses/', ip_data)
                ip_id = ip_response['id']
                
                # Set as primary IP for the device
                device_update = {
                    'primary_ip4': ip_id
                }
                nb.session.patch(f"{nb.api_url}dcim/devices/{device_id}/", json=device_update)
                print("✓ Added primary IP address")
            except Exception as e:
                print(f"✗ Failed to add primary IP: {e}")
            
        except Exception as e:
            print(f"✗ Failed to create Verona router: {e}")
            return
    else:
        device_id = device_response['results'][0]['id']
        print(f"✓ Verona router already exists (ID: {device_id})")
    
    print(f"\n=== Summary ===")
    print(f"Site: Verona (ID: {site_id})")
    print(f"Device: verona-router (ID: {device_id})")
    print(f"\nYou can now run update_netbox_verona.py to add all the subnet and interface data.")


if __name__ == "__main__":
    main()