from util import (
    get_hwnetid,
)
from util_sfp import (
    sfp_ics_send_macsec_rule,
    sfp_ics_send_macsec_map,
    sfp_ics_send_macsec_secy,
    sfp_ics_send_macsec_sc,
    sfp_ics_send_macsec_sa,
    sfp_ics_update_macsec,
)

import time
import yaml

ETH_SPEED_STRINGS = [
    "ETH_SPEED_10",
    "ETH_SPEED_100",
    "ETH_SPEED_1000",
    "ETH_SPEED_2500",
    "ETH_SPEED_5000",
    "ETH_SPEED_10000",
    "ETH_SPEED_AUTO",
]

ETH_DUPLEX_STRINGS = [
    "ETH_DUPLEX_FULL",
    "ETH_DUPLEX_HALF",
]

ETH_MODE_STRINGS = [
    "ETH_MODE_MASTER",
    "ETH_MODE_SLAVE",
    "ETH_MODE_AUTO",
]

ETH_REPORT_LINK_UP_IDX = 0
ETH_REPORT_SPEED_IDX = 1
ETH_REPORT_DUPLEX_IDX = 2
ETH_REPORT_NETID_LSB_IDX = 3
ETH_REPORT_NETID_MSB_IDX = 4
ETH_REPORT_MODE_IDX = 5


def load_macsec_from_yaml(device, netid_name, yml, sfp):
    netid = get_hwnetid(netid_name)
    with open("yaml/" + yml, "r") as file:
        macsec_cfg = yaml.safe_load(file)  # read macsec configuration from yaml
        if sfp:  # ics sfp module - load over i2c with ics config subcommands
            en = 1
            rx = 0
            rule = 0
            map = 0
            secy = 0
            sc = 0
            sa = 0
            nvm = 1
            clr = 0
            rst = 1
            # clear/reset any current macsec configuration
            sfp_ics_update_macsec(
                device, netid, rx, rule, map, secy, sc, sa, nvm, en, clr, rst
            )
            time.sleep(
                1
            )  # allow time for sfp to write macsec configuration to phy over mdio
            # tx config
            if macsec_cfg["tx"]:
                rx = 0
                rst = 0
                if macsec_cfg["tx"]["rule"]:
                    rule = 1
                    sfp_ics_send_macsec_rule(
                        device, netid, macsec_cfg["tx"]["rule"]
                    )  # write macsec rule to sfp
                if macsec_cfg["tx"]["map"]:
                    map = 1
                    sfp_ics_send_macsec_map(
                        device, netid, macsec_cfg["tx"]["map"]
                    )  # write macsec map to sfp
                if macsec_cfg["tx"]["secy"]:
                    secy = 1
                    sfp_ics_send_macsec_secy(
                        device, netid, macsec_cfg["tx"]["secy"]
                    )  # write macsec secy to sfp
                if macsec_cfg["tx"]["sc"]:
                    sc = 1
                    sfp_ics_send_macsec_sc(
                        device, netid, macsec_cfg["tx"]["sc"]
                    )  # write macsec sc to sfp
                if macsec_cfg["tx"]["sa0"] and macsec_cfg["tx"]["sa1"]:
                    sa = 1
                    sfp_ics_send_macsec_sa(
                        device, netid, macsec_cfg["tx"]["sa0"]
                    )  # write macsec sa0 to sfp
                    sfp_ics_update_macsec(
                        device, netid, rx, 0, 0, 0, 0, sa, 0, en, clr, rst
                    )  # push macsec sa config to phy
                    time.sleep(
                        0.5
                    )  # allow time for sfp to write macsec configuration to phy over mdio
                    sfp_ics_send_macsec_sa(
                        device, netid, macsec_cfg["tx"]["sa1"]
                    )  # write macsec sa1 to sfp
                sfp_ics_update_macsec(
                    device,
                    netid,
                    rx,
                    rule,
                    map,
                    secy,
                    sc,
                    sa,
                    nvm,
                    en,
                    clr,
                    rst,
                )  # push entire macsec config to phy
                time.sleep(
                    1
                )  # allow time for sfp to write entire macsec configuration to phy over mdio
            # rx config
            if macsec_cfg["rx"]:
                rx = 1
                rst = 0
                if macsec_cfg["rx"]["rule"]:
                    rule = 1
                    sfp_ics_send_macsec_rule(
                        device, netid, macsec_cfg["rx"]["rule"]
                    )  # write macsec rule to sfp
                if macsec_cfg["rx"]["map"]:
                    map = 1
                    sfp_ics_send_macsec_map(
                        device, netid, macsec_cfg["rx"]["map"]
                    )  # write macsec map to sfp
                if macsec_cfg["rx"]["secy"]:
                    secy = 1
                    sfp_ics_send_macsec_secy(
                        device, netid, macsec_cfg["rx"]["secy"]
                    )  # write macsec secy to sfp
                if macsec_cfg["rx"]["sc"]:
                    sc = 1
                    sfp_ics_send_macsec_sc(
                        device, netid, macsec_cfg["rx"]["sc"]
                    )  # write macsec sc to sfp
                if macsec_cfg["rx"]["sa0"] and macsec_cfg["rx"]["sa1"]:
                    sa = 1
                    sfp_ics_send_macsec_sa(
                        device, netid, macsec_cfg["rx"]["sa0"]
                    )  # write macsec sa0 to sfp
                    sfp_ics_update_macsec(
                        device, netid, rx, 0, 0, 0, 0, sa, 0, en, clr, rst
                    )  # push macsec sa config to phy
                    time.sleep(
                        0.5
                    )  # allow time for sfp to write macsec configuration to phy over mdio
                    sfp_ics_send_macsec_sa(
                        device, netid, macsec_cfg["rx"]["sa1"]
                    )  # write macsec sa1 to sfp
                sfp_ics_update_macsec(
                    device,
                    netid,
                    rx,
                    rule,
                    map,
                    secy,
                    sc,
                    sa,
                    nvm,
                    en,
                    clr,
                    rst,
                )  # push entire macsec config to phy
                time.sleep(
                    1
                )  # allow time for sfp to write entire macsec configuration to phy over mdio
        else:  # non-sfp module
            pass  # TODO write device settings with the macsec config
    # print macsec confirmation
    print(f"\nSuccessfully configured MACsec on {netid_name}.")
