
from typing import Any, Dict, Optional, Callable
#from acex.models.composed_configuration import ComposedConfiguration
from acex_devkit.models.composed_configuration import ComposedConfiguration
from acex.plugins.neds.core import NetworkElementDriver, TransportBase
from netmiko import ConnectHandler

from acex_devkit.drivers import NetworkElementDriver
from acex_devkit.configdiffer import Diff

from .renderer import CiscoIOSCLIRenderer
from .parser import CiscoIOSCLIParser


class CiscoIOSTransport(TransportBase):
    def connect(self) -> None:
        """Connect to the Cisco IOS CLI device."""
        # Implement connection logic
        pass

    def send(self, payload: Any) -> None:
        """Send the rendered configuration to the device."""
        # Implement sending logic
        pass

    def verify(self) -> bool:
        """Verify the configuration on the device."""
        # Implement verification logic
        return True

    def rollback(self) -> None:
        """Rollback the configuration if verification fails."""
        # Implement rollback logic
        pass


class CiscoIOSCLIDriver(NetworkElementDriver):
    """Cisco IOS CLI driver."""

    renderer_class = CiscoIOSCLIRenderer
    transport_class = CiscoIOSTransport
    parser_class = CiscoIOSCLIParser

    def render(self, configuration: ComposedConfiguration, asset):
        """Render the configuration for a Cisco IOS CLI device."""
        # Call the base class render method
        config = self.renderer.render(configuration, asset)
        return config

    def parse(self, configuration: str) -> ComposedConfiguration: 
        return self.parser.parse(configuration)


    def render_patch(self, diff: Diff, node_instance: "NodeInstance"): 
        """
        Render specific commands for patching based on a diff.
        """
        return self.renderer.render_patch(diff, node_instance)


    def apply_patch(self, diff: Diff, node_instance, connection):
        """
        Takes a diff and applies config to device
        """
        commands = self.render_patch(diff, node_instance=node_instance)

        # commands = commands.splitlines()
        commands = [c.lstrip() for c in commands.splitlines() if c.strip() != "!"]

        cisco_device = {
            "device_type": "cisco_ios",
            "host": connection,
            "username": "admin",
            "password": "polly123",
            # "secret": "enablepassword",  # enable password
        }

        # Skapa anslutning
        connection = ConnectHandler(**cisco_device)

        # Gå in i enable mode
        connection.enable()

        # Skicka konfig
        output = connection.send_config_set(commands)

        # Stäng anslutning
        connection.disconnect()