/*
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#pragma once

#include <ipmid/api-types.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/timer.hpp>
#include <variantvisitors.hpp>
#include <vector>

#define FAN_SENSOR_NOT_PRESENT (0 << 0)
#define FAN_SENSOR_PRESENT (1 << 0)
#define FAN_NOT_PRESENT (0 << 1)
#define FAN_PRESENT (1 << 1)

namespace ipmi
{

// TODO: Service names may change. Worth to consider dynamic detection.
static constexpr const char* fanService = "xyz.openbmc_project.FanSensor";
static constexpr const char* buttonService =
    "xyz.openbmc_project.Chassis.Buttons";
static constexpr const char* ledServicePrefix =
    "xyz.openbmc_project.LED.Controller.";

static constexpr const char* ledPathPrefix =
    "/xyz/openbmc_project/led/physical/";
static constexpr const char* fanPwmPath =
    "/xyz/openbmc_project/sensors/fan_pwm/Pwm_";
static constexpr const char* fanTachPathPrefix =
    "/xyz/openbmc_project/sensors/fan_tach/Fan_";

static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value";
static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons";
static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical";

static constexpr const char* busPropertyIntf =
    "org.freedesktop.DBus.Properties";
static constexpr const char* ledStateStr =
    "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On

/** @enum MtmLvl
.*
 *  Manufacturing command access levels
 */
enum class MtmLvl
{
    mtmNotRunning = 0x00,
    mtmExpired = 0x01,
    mtmAvailable = 0x02,
};

enum class SmActionGet : uint8_t
{
    sample = 0,
    ignore = 1,
    revert = 2
};

enum class SmActionSet : uint8_t
{
    forceDeasserted = 0,
    forceAsserted = 1,
    revert = 2
};

enum class SmSignalGet : uint8_t
{
    smPowerButton = 0,
    smResetButton = 1,
    smSleepButton,
    smNMIButton = 3,
    smChassisIntrusion = 4,
    smPowerGood,
    smPowerRequestGet,
    smSleepRequestGet,
    smFrbTimerHaltGet,
    smForceUpdate,
    smRingIndication,
    smCarrierDetect,
    smIdentifyButton = 0xc,
    smFanPwmGet = 0xd,
    smSignalReserved,
    smFanTachometerGet = 0xf,
    smNcsiDiag = 0x10,
    smGetSignalMax
};

enum class SmSignalSet : uint8_t
{
    smPowerLed = 0,
    smPowerFaultLed,
    smClusterLed,
    smDiskFaultLed,
    smCoolingFaultLed,
    smFanPowerSpeed = 5,
    smPowerRequestSet,
    smSleepRequestSet,
    smAcpiSci,
    smSpeaker,
    smFanPackFaultLed,
    smCpuFailLed,
    smDimmFailLed,
    smIdentifyLed,
    smHddLed,
    smSystemReadyLed,
    smLcdBacklight = 0x10,
    smSetSignalMax
};

struct SetSmSignalReq
{
    SmSignalSet Signal;
    uint8_t Instance;
    SmActionSet Action;
    uint8_t Value;
};

class LedProperty
{
    SmSignalSet signal;
    std::string name;
    std::string prevState;
    std::string currentState;
    bool isLocked;

  public:
    LedProperty(SmSignalSet signal_, std::string name_) :
        signal(signal_), name(name_), prevState(""), isLocked(false)
    {
    }

    LedProperty() = delete;

    SmSignalSet getSignal() const
    {
        return signal;
    }

    void setLock(const bool& lock)
    {
        isLocked = lock;
    }
    void setPrevState(const std::string& state)
    {
        prevState = state;
    }
    void setCurrState(const std::string& state)
    {
        currentState = state;
    }
    std::string getCurrState() const
    {
        return currentState;
    }
    bool getLock() const
    {
        return isLocked;
    }
    std::string getPrevState() const
    {
        return prevState;
    }
    std::string getName() const
    {
        return name;
    }
};

/** @class Manufacturing
 *
 *  @brief Implemet commands to support Manufacturing Test Mode.
 */
class Manufacturing
{
    std::string path;
    std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
    std::vector<LedProperty> ledPropertyList;
    void initData();

  public:
    Manufacturing();

    ipmi_return_codes detectAccessLvl(ipmi_request_t request,
                                      ipmi_data_len_t req_len);

    LedProperty* findLedProperty(const SmSignalSet& signal)
    {
        auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
                               [&signal](const LedProperty& led) {
                                   return led.getSignal() == signal;
                               });
        if (it != ledPropertyList.end())
        {
            return &(*it);
        }
        return nullptr;
    }

    std::string getLedPropertyName(const SmSignalSet signal)
    {
        LedProperty* led = findLedProperty(signal);
        if (led != nullptr)
        {
            return led->getName();
        }
        else
        {
            return "";
        }
    }

    int8_t getProperty(const std::string& service, const std::string& path,
                       const std::string& interface,
                       const std::string& propertyName, ipmi::Value* value);
    int8_t setProperty(const std::string& service, const std::string& path,
                       const std::string& interface,
                       const std::string& propertyName, ipmi::Value value);
    int8_t disablePidControlService(const bool disable);

    void revertTimerHandler();

    MtmLvl getAccessLvl(void)
    {
        static MtmLvl mtmMode = MtmLvl::mtmNotRunning;
        if (mtmMode != MtmLvl::mtmExpired)
        {
            ipmi::Value mode;
            if (getProperty("xyz.openbmc_project.SpecialMode",
                            "/xyz/openbmc_project/security/specialMode",
                            "xyz.openbmc_project.Security.SpecialMode",
                            "SpecialMode", &mode) != 0)
            {
                mtmMode = MtmLvl::mtmExpired;
                return mtmMode;
            }
            mtmMode = static_cast<MtmLvl>(std::get<std::uint8_t>(mode));
        }
        return mtmMode;
    }

    bool revertFanPWM = false;
    bool revertLedCallback = false;
    phosphor::Timer revertTimer;
};

} // namespace ipmi
