import os
import sys
import yaml

def get_eth0_ip():
    """Get the last octet of the IP address of eth0"""
    try:
        # Run the command to get the IP address of eth0
        ip_output = os.popen("ip addr show eth0 | grep inet | awk '{ print $2 }'").read().strip()
        if not ip_output:
            print("Error: No IP address found for eth0.")
            return None
        # Extract the last octet of the IP address
        ip_parts = ip_output.split('/')
        ip_address = ip_parts[0]
        last_octet = ip_address.split('.')[-1]
        return last_octet
    except Exception as e:
        print(f"Error while fetching eth0 IP: {e}")
        return None

def set_dns_in_netplan(xxx_value):
    # DNS addresses for each interface
    eth0_dns = ["78.157.39.60"]
    eth1_dns = ["172.22.60.1"]
    eth1_search_domains = ["abrisham.local", "roomeet.local"]

    # Path to the Netplan configuration directory
    netplan_dir = "/etc/netplan"
    
    # Check if the Netplan directory exists
    if not os.path.isdir(netplan_dir):
        print("Netplan configuration directory does not exist.")
        return

    # Find all .yaml files in the /etc/netplan directory
    netplan_files = [f for f in os.listdir(netplan_dir) if f.endswith('.yaml')]
    
    # If no YAML files are found, print a message and exit
    if not netplan_files:
        print("No Netplan YAML files found.")
        return
    
    # Get the last octet of eth0 IP to use for eth1 IP
    last_octet = get_eth0_ip()
    if not last_octet:
        return

    # Create eth1 IP address dynamically
    eth1_ip = f"172.22.{xxx_value}.{last_octet}/21"

    # Loop over each Netplan file found in the directory
    for netplan_file in netplan_files:
        # Full path to the Netplan file
        file_path = os.path.join(netplan_dir, netplan_file)
        
        print(f"Processing {file_path}...")

        # Open and read the YAML file
        with open(file_path, 'r') as f:
            try:
                # Load the YAML content into a Python dictionary
                netplan_config = yaml.safe_load(f)
            except yaml.YAMLError as e:
                # Handle any errors during YAML reading
                print(f"Error reading {file_path}: {e}")
                continue

        # Check if 'network' and 'ethernets' sections exist in the YAML
        if 'network' in netplan_config and 'ethernets' in netplan_config['network']:
            # Check and update DNS for eth0 if it exists
            if 'eth0' in netplan_config['network']['ethernets']:
                print("Updating DNS for eth0...")
                netplan_config['network']['ethernets']['eth0']['nameservers'] = {'addresses': eth0_dns}
                
            # Check if eth1 exists physically
            eth1_exists = os.system("ip link show eth1") == 0  # Check if eth1 interface exists

            if eth1_exists:
                print("eth1 exists physically. Checking if DNS and IP are configured...")

                # Check if eth1 is configured in netplan
                if 'eth1' not in netplan_config['network']['ethernets']:
                    print("eth1 exists but no configuration found in netplan. Adding configuration...")
                    # Adding IP address and DNS for eth1 (without dhcp4: false)
                    netplan_config['network']['ethernets']['eth1'] = {
                        'addresses': [eth1_ip],
                        'nameservers': {
                            'addresses': eth1_dns,
                            'search': eth1_search_domains
                        }
                    }
                else:
                    # eth1 exists in netplan, check DNS and IP settings
                    print("eth1 configuration found. Updating DNS and IP settings...")
                    netplan_config['network']['ethernets']['eth1']['addresses'] = [eth1_ip]
                    netplan_config['network']['ethernets']['eth1']['nameservers'] = {
                        'addresses': eth1_dns,
                        'search': eth1_search_domains
                    }
                    # If dhcp4 exists, remove it
                    if 'dhcp4' in netplan_config['network']['ethernets']['eth1']:
                        print("Removing dhcp4 configuration for eth1...")
                        del netplan_config['network']['ethernets']['eth1']['dhcp4']

            else:
                # If eth1 does not exist physically, print an error message and exit
                print("Error: eth1 does not exist physically. Exiting.")
                return
        
        else:
            # If no 'ethernets' section is found in the file, print a message and skip
            print(f"No 'ethernets' section found in {file_path}. Skipping.")

        # Save the modified YAML content back to the file
        with open(file_path, 'w') as f:
            try:
                # Write the updated YAML content back, ensuring proper indentation
                yaml.safe_dump(netplan_config, f, default_flow_style=False, allow_unicode=True, indent=2)
                print(f"Changes applied to {file_path}")
            except yaml.YAMLError as e:
                # Handle any errors while writing the file
                print(f"Error saving {file_path}: {e}")

    # Apply the changes with the 'netplan apply' command to make them take effect
    os.system("sudo netplan apply")
    print("DNS and search domains have been updated and changes have been applied with Netplan.")

# Main function to set DNS for eth0 and eth1 interfaces
if __name__ == "__main__":
    # Ensure that the user provides a valid xxx_value as a parameter
    if len(sys.argv) != 2:
        print("Usage: python3 set_dns_netplan.py <xxx_value>")
        print("Error: The <xxx_value> parameter is required. Please provide an integer between 1 and 254.")
        sys.exit(1)

    # Get the xxx_value passed as a parameter
    xxx_value = sys.argv[1]
    
    # Validate the xxx_value to ensure it's a valid integer between 1 and 254
    try:
        xxx_value = int(xxx_value)
        if not (1 <= xxx_value <= 254):
            raise ValueError("xxx_value must be between 1 and 254.")
    except ValueError as e:
        print(f"Error: {e}")
        sys.exit(1)

    set_dns_in_netplan(xxx_value)

