#! /usr/bin/python3
import iota.harness.api as api
import iota.test.utils.naples_host as host
import iota.test.iris.config.netagent.hw_push_config as hw_config
from .sriov_utils import SetVFMac
from .sriov_utils import GetSupportedVFs
from .sriov_utils import CreateVFs
from .sriov_utils import SetVFTrust
from .sriov_utils import SetVFNdevMac


def Setup(tc):
    host = None
    for _node in api.GetNaplesHostnames():
        if api.IsNaplesNode(_node) and api.GetNodeOs(_node) == "linux":
            host = _node
            break
    
    if not host:
        api.Logger.error("Unable to find a Naples node with linux os")
        return api.types.status.ERROR

    tc.host = host
    tc.pf = api.GetNaplesHostInterfaces(host)[0]
    tc.num_vfs = GetSupportedVFs(tc.host, tc.pf)
    api.Logger.info("Host %s PF %s supports %d VFs" % (tc.host, tc.pf, tc.num_vfs))

    if tc.num_vfs == 0:
        api.Logger.warn("Max supported VFs on host %s is 0, expected non-zero" % host)
        return api.types.status.ERROR

    if CreateVFs(tc.host, tc.pf, tc.num_vfs)!= api.types.status.SUCCESS:
        return api.types.status.ERROR

    return api.types.status.SUCCESS


def Trigger(tc):
    # need to check ifconfig with both trust off (default) and trust on
    #
    #    assume trust is off by default
    #    get VF name
    #    try ifconfig <vfname> hw ether <macaddr>
    #        with trust off, should fail with no permission
    #    ip link set dev <PF> vf <vf-id> trust on
    #    try ifconfig <vfname> hw ether <macaddr>
    #        with trust on, should succeed
    #    ip link set dev <PF> vf <vf-id> trust off
    #
    hostname = tc.host
    pf = tc.pf
    max_vfs = tc.num_vfs

    
    num_vfs = min([max_vfs, 255])
    if CreateVFs(hostname, pf, num_vfs) != api.types.status.SUCCESS:
        return api.types.status.ERROR

    for vfid in range(num_vfs):
        api.Logger.info("Check VF %d trust host %s PF %s" % (vfid, hostname, pf))
        mac = "00:22:44:66:88:%02x" % vfid
        if SetVFTrust(hostname, pf, vfid, "off") != api.types.status.SUCCESS:
            return api.types.status.FAILURE
        if SetVFNdevMac(hostname, pf, vfid, mac) == api.types.status.SUCCESS:
            api.Logger.error("Set mac succeeded on VF %d with trust off on host %s pf %s"
                             % (vfid, hostname, pf))
            return api.types.status.FAILURE
        api.Logger.info("VF %d trust off passed" % vfid)

        if SetVFTrust(hostname, pf, vfid, "on") != api.types.status.SUCCESS:
            return api.types.status.FAILURE
        if SetVFNdevMac(hostname, pf, vfid, mac) != api.types.status.SUCCESS:
            api.Logger.error("Set mac succeeded on VF %d with trust on host %s pf %s"
                             % (vfid, hostname, pf))
            return api.types.status.FAILURE
        api.Logger.info("VF %d trust on passed" % vfid)

    return api.types.status.SUCCESS

def Verify(tc):
    return api.types.status.SUCCESS

def Teardown(tc):
    hostname = tc.host
    os_name = api.GetNodeOs(hostname)
    # restore the workloads on the one host we tested
    if host.UnloadDriver(os_name, hostname, "eth") is api.types.status.FAILURE:
        return api.types.status.FAILURE
    if host.LoadDriver(os_name, hostname) is api.types.status.FAILURE:
        return api.types.status.FAILURE

    hw_config.ReAddWorkloads(hostname)

    return api.types.status.SUCCESS