#!/usr/bin/env python3
"""
Validate autoinstall configuration against Ubuntu's schema.
This script provides basic validation to check if our autoinstall config
complies with the official schema structure.
"""

import yaml
import sys
from pathlib import Path


def load_autoinstall_config(template_path: str) -> dict:
    """Load the autoinstall configuration from the template file."""
    with open(template_path, "r") as f:
        content = f.read()

    # Parse the cloud-config YAML
    config = yaml.safe_load(content)

    # Extract the autoinstall section
    if "autoinstall" in config:
        return config["autoinstall"]
    else:
        raise ValueError("No autoinstall section found in cloud-config")


def validate_required_fields(config: dict) -> list:
    """Validate required fields according to schema."""
    errors = []

    # Check version field (required)
    if "version" not in config:
        errors.append("Missing required field: version")
    elif not isinstance(config["version"], int) or config["version"] != 1:
        errors.append("Invalid version: must be integer 1")

    return errors


def validate_identity_section(config: dict) -> list:
    """Validate identity section."""
    errors = []

    if "identity" in config:
        identity = config["identity"]
        required_fields = ["username", "hostname", "password"]

        for field in required_fields:
            if field not in identity:
                errors.append(f"Identity section missing required field: {field}")

        # Additional validation
        if "username" in identity and not isinstance(identity["username"], str):
            errors.append("Identity username must be a string")

        if "hostname" in identity and not isinstance(identity["hostname"], str):
            errors.append("Identity hostname must be a string")

    return errors


def validate_network_section(config: dict) -> list:
    """Validate network section."""
    errors = []

    if "network" in config:
        network = config["network"]

        if "version" not in network:
            errors.append("Network section missing required field: version")
        elif network["version"] != 2:
            errors.append("Network version must be 2")

    return errors


def validate_keyboard_section(config: dict) -> list:
    """Validate keyboard section."""
    errors = []

    if "keyboard" in config:
        keyboard = config["keyboard"]

        if "layout" not in keyboard:
            errors.append("Keyboard section missing required field: layout")

    return errors


def validate_ssh_section(config: dict) -> list:
    """Validate SSH section."""
    errors = []

    if "ssh" in config:
        ssh = config["ssh"]

        if "install-server" in ssh and not isinstance(ssh["install-server"], bool):
            errors.append("SSH install-server must be boolean")

        if "authorized-keys" in ssh and not isinstance(ssh["authorized-keys"], list):
            errors.append("SSH authorized-keys must be an array")

        if "allow-pw" in ssh and not isinstance(ssh["allow-pw"], bool):
            errors.append("SSH allow-pw must be boolean")

    return errors


def validate_packages_section(config: dict) -> list:
    """Validate packages section."""
    errors = []

    if "packages" in config:
        packages = config["packages"]

        if not isinstance(packages, list):
            errors.append("Packages must be an array")
        else:
            for i, package in enumerate(packages):
                if not isinstance(package, str):
                    errors.append(f"Package at index {i} must be a string")

    return errors


def validate_commands_sections(config: dict) -> list:
    """Validate early-commands and late-commands sections."""
    errors = []

    for section_name in ["early-commands", "late-commands"]:
        if section_name in config:
            commands = config[section_name]

            if not isinstance(commands, list):
                errors.append(f"{section_name} must be an array")
            else:
                for i, command in enumerate(commands):
                    if not isinstance(command, (str, list)):
                        errors.append(
                            f"{section_name} item at index {i} must be string or array"
                        )
                    elif isinstance(command, list):
                        for j, cmd_part in enumerate(command):
                            if not isinstance(cmd_part, str):
                                errors.append(
                                    f"{section_name}[{i}][{j}] must be a string"
                                )

    return errors


def validate_shutdown_section(config: dict) -> list:
    """Validate shutdown section."""
    errors = []

    if "shutdown" in config:
        shutdown = config["shutdown"]
        valid_values = ["reboot", "poweroff"]

        if shutdown not in valid_values:
            errors.append(f"Shutdown must be one of: {valid_values}")

    return errors


def main():
    """Main validation function."""
    template_path = Path(__file__).parent / "cloud-init-template.yaml"

    if not template_path.exists():
        print(f"Error: Template file not found at {template_path}")
        sys.exit(1)

    try:
        # Load the autoinstall configuration
        print(f"Loading autoinstall config from {template_path}")
        config = load_autoinstall_config(str(template_path))

        # Run validation checks
        all_errors = []

        all_errors.extend(validate_required_fields(config))
        all_errors.extend(validate_identity_section(config))
        all_errors.extend(validate_network_section(config))
        all_errors.extend(validate_keyboard_section(config))
        all_errors.extend(validate_ssh_section(config))
        all_errors.extend(validate_packages_section(config))
        all_errors.extend(validate_commands_sections(config))
        all_errors.extend(validate_shutdown_section(config))

        # Report results
        if all_errors:
            print("\n❌ Validation failed with the following errors:")
            for error in all_errors:
                print(f"  - {error}")
            sys.exit(1)
        else:
            print("\n✅ Autoinstall configuration validation passed!")
            print("Configuration appears to comply with Ubuntu autoinstall schema.")

            # Print summary of detected sections
            sections = list(config.keys())
            print(f"\nDetected sections: {', '.join(sorted(sections))}")

    except Exception as e:
        print(f"Error during validation: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
