/**
 * Copyright © 2020 IBM 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 "action.hpp"
#include "and_action.hpp"
#include "chassis.hpp"
#include "compare_presence_action.hpp"
#include "compare_vpd_action.hpp"
#include "configuration.hpp"
#include "device.hpp"
#include "i2c_compare_bit_action.hpp"
#include "i2c_compare_byte_action.hpp"
#include "i2c_compare_bytes_action.hpp"
#include "i2c_interface.hpp"
#include "i2c_write_bit_action.hpp"
#include "i2c_write_byte_action.hpp"
#include "i2c_write_bytes_action.hpp"
#include "if_action.hpp"
#include "not_action.hpp"
#include "or_action.hpp"
#include "pmbus_write_vout_command_action.hpp"
#include "presence_detection.hpp"
#include "rail.hpp"
#include "rule.hpp"
#include "run_rule_action.hpp"
#include "sensor_monitoring.hpp"
#include "set_device_action.hpp"

#include <nlohmann/json.hpp>

#include <cstdint>
#include <filesystem>
#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>

namespace phosphor::power::regulators::config_file_parser
{

/**
 * Parses the specified JSON configuration file.
 *
 * Returns the corresponding C++ Rule and Chassis objects.
 *
 * Throws a ConfigFileParserError if an error occurs.
 *
 * @param pathName configuration file path name
 * @return tuple containing vectors of Rule and Chassis objects
 */
std::tuple<std::vector<std::unique_ptr<Rule>>,
           std::vector<std::unique_ptr<Chassis>>>
    parse(const std::filesystem::path& pathName);

/*
 * Internal implementation details for parse()
 */
namespace internal
{

/**
 * Returns the specified property of the specified JSON element.
 *
 * Throws an invalid_argument exception if the property does not exist.
 *
 * @param element JSON element
 * @param property property name
 */
inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
                                                 const std::string& property)
{
    auto it = element.find(property);
    if (it == element.end())
    {
        throw std::invalid_argument{"Required property missing: " + property};
    }
    return *it;
}

/**
 * Parses a JSON element containing an action.
 *
 * Returns the corresponding C++ Action object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Action object
 */
std::unique_ptr<Action> parseAction(const nlohmann::json& element);

/**
 * Parses a JSON element containing an array of actions.
 *
 * Returns the corresponding C++ Action objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Action objects
 */
std::vector<std::unique_ptr<Action>>
    parseActionArray(const nlohmann::json& element);

/**
 * Parses a JSON element containing an and action.
 *
 * Returns the corresponding C++ AndAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return AndAction object
 */
std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);

/**
 * Parses a JSON element containing a bit position (from 0-7).
 *
 * Returns the corresponding C++ uint8_t value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return uint8_t value
 */
inline uint8_t parseBitPosition(const nlohmann::json& element)
{
    // Verify element contains an integer
    if (!element.is_number_integer())
    {
        throw std::invalid_argument{"Element is not an integer"};
    }
    int value = element.get<int>();
    if ((value < 0) || (value > 7))
    {
        throw std::invalid_argument{"Element is not a bit position"};
    }
    return static_cast<uint8_t>(value);
}

/**
 * Parses a JSON element containing a bit value (0 or 1).
 *
 * Returns the corresponding C++ uint8_t value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return uint8_t value
 */
inline uint8_t parseBitValue(const nlohmann::json& element)
{
    // Verify element contains an integer
    if (!element.is_number_integer())
    {
        throw std::invalid_argument{"Element is not an integer"};
    }
    int value = element.get<int>();
    if ((value < 0) || (value > 1))
    {
        throw std::invalid_argument{"Element is not a bit value"};
    }
    return static_cast<uint8_t>(value);
}

/**
 * Parses a JSON element containing a boolean.
 *
 * Returns the corresponding C++ boolean value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return boolean value
 */
inline bool parseBoolean(const nlohmann::json& element)
{
    // Verify element contains a boolean
    if (!element.is_boolean())
    {
        throw std::invalid_argument{"Element is not a boolean"};
    }
    return element.get<bool>();
}

/**
 * Parses a JSON element containing a chassis.
 *
 * Returns the corresponding C++ Chassis object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Chassis object
 */
std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);

/**
 * Parses a JSON element containing an array of chassis.
 *
 * Returns the corresponding C++ Chassis objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Chassis objects
 */
std::vector<std::unique_ptr<Chassis>>
    parseChassisArray(const nlohmann::json& element);

/**
 * Parses a JSON element containing a compare_presence action.
 *
 * Returns the corresponding C++ ComparePresenceAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return ComparePresenceAction object
 */
std::unique_ptr<ComparePresenceAction>
    parseComparePresence(const nlohmann::json& element);

/**
 * Parses a JSON element containing a compare_vpd action.
 *
 * Returns the corresponding C++ CompareVPDAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return CompareVPDAction object
 */
std::unique_ptr<CompareVPDAction>
    parseCompareVPD(const nlohmann::json& element);

/**
 * Parses a JSON element containing a configuration.
 *
 * Returns the corresponding C++ Configuration object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Configuration object
 */
std::unique_ptr<Configuration>
    parseConfiguration(const nlohmann::json& element);

/**
 * Parses a JSON element containing a device.
 *
 * Returns the corresponding C++ Device object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Device object
 */
std::unique_ptr<Device> parseDevice(const nlohmann::json& element);

/**
 * Parses a JSON element containing an array of devices.
 *
 * Returns the corresponding C++ Device objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Device objects
 */
std::vector<std::unique_ptr<Device>>
    parseDeviceArray(const nlohmann::json& element);

/**
 * Parses a JSON element containing a double (floating point number).
 *
 * Returns the corresponding C++ double value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return double value
 */
inline double parseDouble(const nlohmann::json& element)
{
    // Verify element contains a number (integer or floating point)
    if (!element.is_number())
    {
        throw std::invalid_argument{"Element is not a number"};
    }
    return element.get<double>();
}

/**
 * Parses a JSON element containing a byte value expressed as a hexadecimal
 * string.
 *
 * The JSON number data type does not support the hexadecimal format.  For this
 * reason, hexadecimal byte values are stored as strings in the configuration
 * file.
 *
 * Returns the corresponding C++ uint8_t value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return uint8_t value
 */
inline uint8_t parseHexByte(const nlohmann::json& element)
{
    if (!element.is_string())
    {
        throw std::invalid_argument{"Element is not a string"};
    }
    std::string value = element.get<std::string>();

    bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
                 (value.size() < 5) &&
                 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
                  std::string::npos);
    if (!isHex)
    {
        throw std::invalid_argument{"Element is not hexadecimal string"};
    }
    return static_cast<uint8_t>(std::stoul(value, 0, 0));
}

/**
 * Parses a JSON element containing an array of byte values expressed as a
 * hexadecimal strings.
 *
 * Returns the corresponding C++ uint8_t values.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of uint8_t
 */
std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_compare_bit action.
 *
 * Returns the corresponding C++ I2CCompareBitAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CCompareBitAction object
 */
std::unique_ptr<I2CCompareBitAction>
    parseI2CCompareBit(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_compare_byte action.
 *
 * Returns the corresponding C++ I2CCompareByteAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CCompareByteAction object
 */
std::unique_ptr<I2CCompareByteAction>
    parseI2CCompareByte(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_compare_bytes action.
 *
 * Returns the corresponding C++ I2CCompareBytesAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CCompareBytesAction object
 */
std::unique_ptr<I2CCompareBytesAction>
    parseI2CCompareBytes(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_interface.
 *
 * Returns the corresponding C++ i2c::I2CInterface object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return i2c::I2CInterface object
 */
std::unique_ptr<i2c::I2CInterface>
    parseI2CInterface(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_write_bit action.
 *
 * Returns the corresponding C++ I2CWriteBitAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CWriteBitAction object
 */
std::unique_ptr<I2CWriteBitAction>
    parseI2CWriteBit(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_write_byte action.
 *
 * Returns the corresponding C++ I2CWriteByteAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CWriteByteAction object
 */
std::unique_ptr<I2CWriteByteAction>
    parseI2CWriteByte(const nlohmann::json& element);

/**
 * Parses a JSON element containing an i2c_write_bytes action.
 *
 * Returns the corresponding C++ I2CWriteBytesAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return I2CWriteBytesAction object
 */
std::unique_ptr<I2CWriteBytesAction>
    parseI2CWriteBytes(const nlohmann::json& element);

/**
 * Parses a JSON element containing an if action.
 *
 * Returns the corresponding C++ IfAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return IfAction object
 */
std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);

/**
 * Parses a JSON element containing an 8-bit signed integer.
 *
 * Returns the corresponding C++ int8_t value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return int8_t value
 */
inline int8_t parseInt8(const nlohmann::json& element)
{
    // Verify element contains an integer
    if (!element.is_number_integer())
    {
        throw std::invalid_argument{"Element is not an integer"};
    }
    int value = element.get<int>();
    if ((value < INT8_MIN) || (value > INT8_MAX))
    {
        throw std::invalid_argument{"Element is not an 8-bit signed integer"};
    }
    return static_cast<int8_t>(value);
}

/**
 * Parses a JSON element containing a not action.
 *
 * Returns the corresponding C++ NotAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return NotAction object
 */
std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);

/**
 * Parses a JSON element containing an or action.
 *
 * Returns the corresponding C++ OrAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return OrAction object
 */
std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);

/**
 * Parses a JSON element containing a pmbus_write_vout_command action.
 *
 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return PMBusWriteVoutCommandAction object
 */
std::unique_ptr<PMBusWriteVoutCommandAction>
    parsePMBusWriteVoutCommand(const nlohmann::json& element);

/**
 * Parses a JSON element containing a presence detection operation.
 *
 * Returns the corresponding C++ PresenceDetection object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return PresenceDetection object
 */
std::unique_ptr<PresenceDetection>
    parsePresenceDetection(const nlohmann::json& element);

/**
 * Parses a JSON element containing a rail.
 *
 * Returns the corresponding C++ Rail object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Rail object
 */
std::unique_ptr<Rail> parseRail(const nlohmann::json& element);

/**
 * Parses a JSON element containing an array of rails.
 *
 * Returns the corresponding C++ Rail objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Rail objects
 */
std::vector<std::unique_ptr<Rail>>
    parseRailArray(const nlohmann::json& element);

/**
 * Parses the JSON root element of the entire configuration file.
 *
 * Returns the corresponding C++ Rule and Chassis objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return tuple containing vectors of Rule and Chassis objects
 */
std::tuple<std::vector<std::unique_ptr<Rule>>,
           std::vector<std::unique_ptr<Chassis>>>
    parseRoot(const nlohmann::json& element);

/**
 * Parses a JSON element containing a rule.
 *
 * Returns the corresponding C++ Rule object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return Rule object
 */
std::unique_ptr<Rule> parseRule(const nlohmann::json& element);

/**
 * Parses a JSON element containing an array of rules.
 *
 * Returns the corresponding C++ Rule objects.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Rule objects
 */
std::vector<std::unique_ptr<Rule>>
    parseRuleArray(const nlohmann::json& element);

/**
 * Parses the "rule_id" or "actions" property in a JSON element.
 *
 * The element must contain one property or the other but not both.
 *
 * If the element contains a "rule_id" property, the corresponding C++
 * RunRuleAction object is returned.
 *
 * If the element contains an "actions" property, the corresponding C++ Action
 * objects are returned.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return vector of Action objects
 */
std::vector<std::unique_ptr<Action>>
    parseRuleIDOrActionsProperty(const nlohmann::json& element);

/**
 * Parses a JSON element containing a run_rule action.
 *
 * Returns the corresponding C++ RunRuleAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return RunRuleAction object
 */
std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);

/**
 * Parses a JSON element containing a sensor monitoring operation.
 *
 * Returns the corresponding C++ SensorMonitoring object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return SensorMonitoring object
 */
std::unique_ptr<SensorMonitoring>
    parseSensorMonitoring(const nlohmann::json& element);

/**
 * Parses a JSON element containing a set_device action.
 *
 * Returns the corresponding C++ SetDeviceAction object.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return SetDeviceAction object
 */
std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);

/**
 * Parses a JSON element containing a string.
 *
 * Returns the corresponding C++ string.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @param isEmptyValid indicates whether an empty string value is valid
 * @return string value
 */
inline std::string parseString(const nlohmann::json& element,
                               bool isEmptyValid = false)
{
    if (!element.is_string())
    {
        throw std::invalid_argument{"Element is not a string"};
    }
    std::string value = element.get<std::string>();
    if (value.empty() && !isEmptyValid)
    {
        throw std::invalid_argument{"Element contains an empty string"};
    }
    return value;
}

/**
 * Parses a JSON element containing an 8-bit unsigned integer.
 *
 * Returns the corresponding C++ uint8_t value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return uint8_t value
 */
inline uint8_t parseUint8(const nlohmann::json& element)
{
    // Verify element contains an integer
    if (!element.is_number_integer())
    {
        throw std::invalid_argument{"Element is not an integer"};
    }
    int value = element.get<int>();
    if ((value < 0) || (value > UINT8_MAX))
    {
        throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
    }
    return static_cast<uint8_t>(value);
}

/**
 * Parses a JSON element containing an unsigned integer.
 *
 * Returns the corresponding C++ unsigned int value.
 *
 * Throws an exception if parsing fails.
 *
 * @param element JSON element
 * @return unsigned int value
 */
inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
{
    // Verify element contains an unsigned integer
    if (!element.is_number_unsigned())
    {
        throw std::invalid_argument{"Element is not an unsigned integer"};
    }
    return element.get<unsigned int>();
}

/**
 * Verifies that the specified JSON element is a JSON array.
 *
 * Throws an invalid_argument exception if the element is not an array.
 *
 * @param element JSON element
 */
inline void verifyIsArray(const nlohmann::json& element)
{
    if (!element.is_array())
    {
        throw std::invalid_argument{"Element is not an array"};
    }
}

/**
 * Verifies that the specified JSON element is a JSON object.
 *
 * Throws an invalid_argument exception if the element is not an object.
 *
 * @param element JSON element
 */
inline void verifyIsObject(const nlohmann::json& element)
{
    if (!element.is_object())
    {
        throw std::invalid_argument{"Element is not an object"};
    }
}

/**
 * Verifies that the specified JSON element contains the expected number of
 * properties.
 *
 * Throws an invalid_argument exception if the element contains a different
 * number of properties.  This indicates the element contains an invalid
 * property.
 *
 * @param element JSON element
 * @param expectedCount expected number of properties in element
 */
inline void verifyPropertyCount(const nlohmann::json& element,
                                unsigned int expectedCount)
{
    if (element.size() != expectedCount)
    {
        throw std::invalid_argument{"Element contains an invalid property"};
    }
}

} // namespace internal

} // namespace phosphor::power::regulators::config_file_parser
