#!/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
import variables as var

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
