from napalm_srl import NokiaSRLDriver
from napalm_srl.srl import SRLAPI
from napalm.base import models as napalm_models
from ..base import SCBaseNetconfDriver

from ipaddress import IPv6Address


class SCSLRAPI(SRLAPI):
    """
    This override fixes an issue with IPv6 addresses embedded in URLs when talking
    over GRPCs. Not sure if it's moot with the various TLS
    """

    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        super().__init__(hostname, username, password, timeout, optional_args)

        try:
            IPv6Address(hostname)
            self.target = f"[{hostname}]:{self.gnmi_port}"
        except ValueError:
            pass


class SCNokiaSRLDriver(NokiaSRLDriver, SCBaseNetconfDriver):
    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        """
        Forcing insecure connection for testing purposes
        """
        optional_args = optional_args if optional_args else {}
        optional_args["insecure"] = True
        optional_args["skip_verify"] = True

        optional_args["encoding"] = "JSON_IETF"

        super().__init__(
            hostname, username, password, timeout=timeout, optional_args=optional_args
        )

        self.device = SCSLRAPI(
            hostname, username, password, timeout=timeout, optional_args=optional_args
        )

    def get_config(
        self, retrieve="all", full=False, sanitized=False, format="text"
    ) -> napalm_models.ConfigDict:
        """
        pulling running config via ssh sow we can have it in 'display set' format.
        """
        if format != "text":
            return super().get_config(
                retrieve=retrieve, full=full, sanitized=sanitized, format=format
            )

        config = {"startup": "", "running": "", "candidate": ""}

        with self.ssh_conn() as ssh_device:
            if retrieve in ["all", "running"]:
                config["running"] = ssh_device.send_command("info from running flat")
            if retrieve in ["all", "startup"]:
                config["startup"] = ssh_device.send_command("info from startup flat")
            if retrieve in ["all", "candidate"]:
                config["candidate"] = ssh_device.send_command(
                    "info from candidate flat"
                )

        return config

    def get_inventory(self):
        path = {"/interface/transceiver"}
        path_type = "STATE"
        output = self.device._gnmiGet("", path, path_type)
        transceivers = self._getObj(
            output, *["srl_nokia-interfaces:interface"], default=[]
        )
        result = []
        for t_if in transceivers:
            trans = t_if["transceiver"]

            if "serial-number" not in trans:
                continue

            result.append(
                {
                    "type": "optic",
                    "subtype": trans["ethernet-pmd"],
                    "name": t_if["name"],
                    "part_number": trans["vendor-part-number"],
                    "serial_number": trans["serial-number"],
                }
            )

        return result
