#!/usr/bin/env python3

r"""
State Manager module:

   - Defines Valid states of the system

"""
import os
import re
import sys

from robot.libraries.BuiltIn import BuiltIn

robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
repo_data_dir_path = re.sub('/lib', '/data', robot_pgm_dir_path)
sys.path.append(repo_data_dir_path)

import gen_robot_keyword as keyword  # NOQA
import variables as var              # NOQA

BuiltIn().import_resource("state_manager.robot")
BuiltIn().import_resource("rest_client.robot")

platform_arch_type = os.environ.get('PLATFORM_ARCH_TYPE', '') or \
    BuiltIn().get_variable_value("${PLATFORM_ARCH_TYPE}", default="power")

# We will build eventually the mapping for warm, cold reset as well.
VALID_STATES = {
    'reboot':
    {
        # (Power Policy, BMC state, Chassis State, Host State)
        ('LEAVE_OFF', 'Ready', 'Off', 'Off'),
        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Running'),
        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Off'),
        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Running'),
        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Off'),
        ('ALWAYS_POWER_OFF', 'Ready', 'On', 'Running'),
        ('ALWAYS_POWER_OFF', 'Ready', 'Off', 'Off'),
    },
}

VALID_BOOT_STATES = {
    'Off':  # Valid states when Host is Off.
    {
        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
        (
            "xyz.openbmc_project.State.BMC.BMCState.Ready",
            "xyz.openbmc_project.State.Chassis.PowerState.Off",
            "xyz.openbmc_project.State.Host.HostState.Off",
            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
        ),
    },
    'Reboot':  # Valid states when BMC reset to standby.
    {
        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
        (
            "xyz.openbmc_project.State.BMC.BMCState.Ready",
            "xyz.openbmc_project.State.Chassis.PowerState.Off",
            "xyz.openbmc_project.State.Host.HostState.Off",
            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
        ),
    },
    'Running':  # Valid states when Host is powering on.
    {
        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
        (
            "xyz.openbmc_project.State.BMC.BMCState.Ready",
            "xyz.openbmc_project.State.Chassis.PowerState.On",
            "xyz.openbmc_project.State.Host.HostState.Running",
            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit",
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
        ),
    },
    'Booted':  # Valid state when Host is booted.
    {
        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
        (
            "xyz.openbmc_project.State.BMC.BMCState.Ready",
            "xyz.openbmc_project.State.Chassis.PowerState.On",
            "xyz.openbmc_project.State.Host.HostState.Running",
            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
        ),
    },
    'ResetReload':  # Valid state BMC reset reload when host is booted.
    {
        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
        (
            "xyz.openbmc_project.State.BMC.BMCState.Ready",
            "xyz.openbmc_project.State.Chassis.PowerState.On",
            "xyz.openbmc_project.State.Host.HostState.Running",
            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
        ),
    },
}
REDFISH_VALID_BOOT_STATES = {
    'Off':  # Valid states when Host is Off.
    {
        # (BMC , Chassis , Host , BootProgress)
        (
            "Enabled",
            "Off",
            "Disabled",
            "None",
        ),
    },
    'Reboot':  # Valid states when BMC reset to standby.
    {
        # (BMC , Chassis , Host , BootProgress)
        (
            "Enabled",
            "Off",
            "Disabled",
            "None",
        ),
    },
    'Running':  # Valid states when Host is powering on.
    {
        # (BMC , Chassis , Host , BootProgress)
        (
            "Enabled",
            "On",
            "Enabled",
            "OSRunning",
        ),
    },
    'Booted':  # Valid state when Host is booted.
    {
        # (BMC , Chassis , Host , BootProgress)
        (
            "Enabled",
            "On",
            "Enabled",
            "OSRunning",
        ),
    },
    'ResetReload':  # Valid state BMC reset reload when host is booted.
    {
        # (BMC , Chassis , Host , BootProgress)
        (
            "Enabled",
            "On",
            "Enabled",
            "OSRunning",
        ),
    },
}

if platform_arch_type == "x86":
    VALID_BOOT_STATES_X86 = {}
    for state_name, state_set in VALID_BOOT_STATES.items():
        VALID_BOOT_STATES_X86[state_name] = set()
        for state_tuple in state_set:
            state_tuple_new = tuple(
                x
                for x in state_tuple
                if not (
                    x.startswith("xyz.openbmc_project.State.Boot.Progress")
                    or x.startswith("xyz.openbmc_project.State.OperatingSystem")
                )
            )
            VALID_BOOT_STATES_X86[state_name].add(state_tuple_new)
    VALID_BOOT_STATES = VALID_BOOT_STATES_X86


class state_map():

    def get_boot_state(self):
        r"""
        Return the system state as a tuple of bmc, chassis, host state,
        BootProgress and OperatingSystemState.
        """

        status, state = keyword.run_key("Read Properties  "
                                        + var.SYSTEM_STATE_URI + "enumerate")
        bmc_state = state[var.SYSTEM_STATE_URI + 'bmc0']['CurrentBMCState']
        chassis_state = \
            state[var.SYSTEM_STATE_URI + 'chassis0']['CurrentPowerState']
        host_state = state[var.SYSTEM_STATE_URI + 'host0']['CurrentHostState']
        if platform_arch_type == "x86":
            return (str(bmc_state),
                    str(chassis_state),
                    str(host_state))
        else:
            boot_state = state[var.SYSTEM_STATE_URI + 'host0']['BootProgress']
            os_state = \
                state[var.SYSTEM_STATE_URI + 'host0']['OperatingSystemState']

            return (str(bmc_state),
                    str(chassis_state),
                    str(host_state),
                    str(boot_state),
                    str(os_state))

    def valid_boot_state(self, boot_type, state_set):
        r"""
        Validate a given set of states is valid.

        Description of argument(s):
        boot_type                   Boot type (e.g. off/running/host booted
                                    etc.)
        state_set                   State set (e.g.bmc,chassis,host,
                                    BootProgress,OperatingSystemState)
        """

        if state_set in set(VALID_BOOT_STATES[boot_type]):
            return True
        else:
            return False

    def redfish_valid_boot_state(self, boot_type, state_dict):
        r"""
        Validate a given set of states is valid.

        Description of argument(s):
        boot_type                   Boot type (e.g. off/running/host booted
                                    etc.)
        state_dict                  State dictionary.
        """

        if set(state_dict.values()) in set(REDFISH_VALID_BOOT_STATES[boot_type]):
            return True
        else:
            return False
