#pragma once

#include "tinyxml2.h"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <types.hpp>

#include <map>
#include <sstream>
#include <stack>
#include <string>
#include <variant>
#include <vector>

namespace bios
{
/* Can hold one 'option'
 * For example
 *  <option text="TIS" value="0x0"/>
 */
using OptionType = std::tuple<std::string, ipmi::DbusVariant, std::string>;

/* Can hold one 'options'
 * For example
 *  <options>
 *		<option text="TIS" value="0x0"/>
 *		<option text="PTP FIFO" value="0x1"/>
 *		<option text="PTP CRB" value="0x2"/>
 *	</options>
 */
using OptionTypeVector = std::vector<OptionType>;

/* Can hold one 'knob'
 * For example
 *  <knob  type="scalar" setupType="oneof" name="TpmDeviceInterfaceAttempt"
 *  varstoreIndex="14" prompt="Attempt PTP TPM Device Interface"
 *  description="Attempt PTP TPM Device Interface: PTP FIFO, PTP CRB" size="1"
 *  offset="0x0005" depex="Sif( _LIST_ TpmDevice _EQU_ 0 1 ) _AND_ Sif(
 *  TpmDeviceInterfacePtpFifoSupported _EQU_ 0 OR
 *  TpmDeviceInterfacePtpCrbSupported _EQU_ 0 )" default="0x00"
 *CurrentVal="0x00"> <options> <option text="TIS" value="0x0"/> <option
 *text="PTP FIFO" value="0x1"/> <option text="PTP CRB" value="0x2"/>
 *		</options>
 *	</knob>
 */
using BiosBaseTableTypeEntry =
    std::tuple<std::string, bool, std::string, std::string, std::string,
               ipmi::DbusVariant, ipmi::DbusVariant, OptionTypeVector>;

/* Can hold one 'biosknobs'
 * biosknobs has array of 'knob' */
using BiosBaseTableType = std::map<std::string, BiosBaseTableTypeEntry>;

namespace knob
{
/* These are the operators we support in a 'depex' expression
 * Note: We also support '_LIST_', 'Sif', 'Gif', 'Dif', and 'NOT'. But they are
 * handeled sepeartely. */
enum class DepexOperators
{
    unknown = 0,
    OR,
    AND,
    GT,
    GTE,
    LTE,
    LT,
    EQU,
    NEQ,
    MODULO
};

namespace option
{
/* Can hold one 'option' */
struct option
{
    option(std::string text, std::string value) :
        text(std::move(text)), value(std::move(value))
    {}

    std::string text;
    std::string value;
};
} // namespace option

/* Can hold one 'knob' */
struct knob
{
    knob(std::string nameStr, std::string currentValStr, int currentVal,
         std::string descriptionStr, std::string defaultStr,
         std::string promptStr, std::string depexStr,
         std::string& setupTypeStr) :
        nameStr(std::move(nameStr)),
        currentValStr(std::move(currentValStr)), currentVal(currentVal),
        descriptionStr(std::move(descriptionStr)),
        defaultStr(std::move(defaultStr)), promptStr(std::move(promptStr)),
        depexStr(std::move(depexStr)), depex(false),
        readOnly(("ReadOnly" == setupTypeStr) ? true : false)
    {}

    bool depex;
    bool readOnly;
    int currentVal;

    std::string nameStr;
    std::string currentValStr;
    std::string descriptionStr;
    std::string defaultStr;
    std::string promptStr;
    std::string depexStr;

    /* Can hold one 'options' */
    std::vector<option::option> options;
};
} // namespace knob

/* Class capable of computing 'depex' expression. */
class Depex
{
  public:
    Depex(std::vector<knob::knob>& knobs) : mKnobs(knobs)
    {}

    /* Compute 'depex' expression of all knobs in 'biosknobs'. */
    void compute()
    {
        mError.clear();

        for (auto& knob : mKnobs)
        {
            /* if 'depex' == "TRUE" no need to execute expression. */
            if ("TRUE" == knob.depexStr)
            {
                knob.depex = true;
            }
            else if (!knob.readOnly)
            {
                int value = 0;

                if (!evaluateExpression(knob.depexStr, value))
                {
                    mError.emplace_back("bad depex: " + knob.depexStr +
                                        " in knob: " + knob.nameStr);
                }
                else
                {
                    if (value)
                    {
                        knob.depex = true;
                    }
                }
            }
        }
    }

    /* Returns the number of 'knob's which have a bad 'depex' expression. */
    size_t getErrorCount()
    {
        return mError.size();
    }

    /* Prints all the 'knob's which have a bad 'depex' expression. */
    void printError()
    {
        for (auto& error : mError)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                error.c_str());
        }
    }

  private:
    /* Returns 'true' if the argument string is a number. */
    bool isNumber(const std::string& s)
    {
        return !s.empty() &&
               std::find_if(s.begin(), s.end(), [](unsigned char c) {
                   return !std::isdigit(c);
               }) == s.end();
    }

    /* Returns 'true' if the argument string is hex representation of a number.
     */
    bool isHexNotation(std::string const& s)
    {
        return s.compare(0, 2, "0x") == 0 && s.size() > 2 &&
               s.find_first_not_of("0123456789abcdefABCDEF", 2) ==
                   std::string::npos;
    }

    /* Function to find current value of a 'knob'
     * search is done using 'knob' attribute 'name' */
    bool getValue(std::string& variableName, int& value)
    {
        for (auto& knob : mKnobs)
        {
            if (knob.nameStr == variableName)
            {
                value = knob.currentVal;
                return true;
            }
        }

        std::string error =
            "Unable to find knob: " + variableName + " in knob list\n";
        phosphor::logging::log<phosphor::logging::level::ERR>(error.c_str());

        return false;
    }

    /* Get the expression enclosed within brackets, i.e., between '(' and ')' */
    bool getSubExpression(const std::string& expression,
                          std::string& subExpression, size_t& i)
    {
        int level = 1;
        subExpression.clear();

        for (; i < expression.length(); i++)
        {
            if (expression[i] == '(')
            {
                ++level;
            }
            else if (expression[i] == ')')
            {
                --level;
                if (level == 0)
                {
                    break;
                }
            }

            subExpression.push_back(expression[i]);
        }

        if (!subExpression.empty())
        {
            return true;
        }

        return false;
    }

    /* Function to handle operator '_LIST_'
     * Convert a '_LIST_' expression to a normal expression
     * Example "_LIST_ VariableA _EQU_ 0 1" is converted to "VariableA _EQU_ 0
     * OR VariableA _EQU_ 1" */
    bool getListExpression(const std::string& expression,
                           std::string& subExpression, size_t& i)
    {
        subExpression.clear();

        int cnt = 0;
        std::string variableStr;
        std::string operatorStr;

        for (; i < expression.length(); i++)
        {
            if (expression[i] == '(')
            {
                return false;
            }
            else if (expression[i] == ')')
            {
                break;
            }
            else if (expression[i] == ' ')
            {
                /* whitespace */
                continue;
            }
            else
            {
                std::string word;

                /* Get the next word in expression string */
                while ((i < expression.length()) && (expression[i] != ' '))
                {
                    word.push_back(expression[i++]);
                }

                if (word == "_OR_" || word == "OR" || word == "_AND_" ||
                    word == "AND" || word == "NOT")
                {
                    i = i - word.length();
                    break;
                }

                ++cnt;

                if (cnt == 1)
                {
                    variableStr = word;
                }
                else if (cnt == 2)
                {
                    operatorStr = word;
                }
                else
                {
                    if (cnt > 3)
                    {
                        subExpression += " OR ";
                    }

                    subExpression += "( ";
                    subExpression += variableStr;
                    subExpression += " ";
                    subExpression += operatorStr;
                    subExpression += " ";
                    subExpression += word;
                    subExpression += " )";
                }
            }
        }

        if (!subExpression.empty())
        {
            return true;
        }

        return false;
    }

    /* Function to handle operator 'NOT'
     * 1) Find the variable
     * 2) apply NOT on the variable */
    bool getNotValue(const std::string& expression, size_t& i, int& value)
    {
        std::string word;

        for (; i < expression.length(); i++)
        {
            if (expression[i] == ' ')
            {
                /* whitespace */
                continue;
            }
            else
            {
                /* Get the next word in expression string */
                while ((i < expression.length()) && (expression[i] != ' '))
                {
                    word.push_back(expression[i++]);
                }

                break;
            }
        }

        if (!word.empty())
        {
            if (getValue(word, value))
            {
                value = !value;
                return true;
            }
        }

        return false;
    }

    /* 1) Pop one operator from operator stack, example 'OR'
     * 2) Pop two variable from variable stack, example VarA and VarB
     * 3) Push back result of 'VarA OR VarB' to variable stack
     * 4) Repeat till operator stack is empty
     *
     * The last variable in variable stack is the output of the expression. */
    bool evaluateExprStack(std::stack<int>& values,
                           std::stack<knob::DepexOperators>& operators,
                           int& output)
    {
        if (values.size() != (operators.size() + 1))
        {
            return false;
        }

        while (!operators.empty())
        {
            int b = values.top();
            values.pop();

            int a = values.top();
            values.pop();

            switch (operators.top())
            {
                case knob::DepexOperators::OR:
                    values.emplace(a | b);
                    break;

                case knob::DepexOperators::AND:
                    values.emplace(a & b);
                    break;

                case knob::DepexOperators::EQU:
                    if (a == b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::NEQ:
                    if (a != b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::LTE:
                    if (a <= b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::LT:
                    if (a < b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::GTE:
                    if (a >= b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::GT:
                    if (a > b)
                    {
                        values.emplace(1);
                        break;
                    }

                    values.emplace(0);
                    break;

                case knob::DepexOperators::MODULO:
                    if (b == 0)
                    {
                        return false;
                    }
                    values.emplace(a % b);
                    break;

                default:
                    return false;
            }

            operators.pop();
        }

        if (values.size() == 1)
        {
            output = values.top();
            values.pop();

            return true;
        }

        return false;
    }

    /* Evaluvate one 'depex' expression
     * 1) Find a word in expression string
     * 2) If word is a variable push to variable stack
     * 3) If word is a operator push to operator stack
     *
     * Execute the stack at end to get the result of expression. */
    bool evaluateExpression(const std::string& expression, int& output)
    {
        if (expression.empty())
        {
            return false;
        }

        size_t i;
        int value;
        std::stack<int> values;
        std::stack<knob::DepexOperators> operators;
        std::string subExpression;

        for (i = 0; i < expression.length(); i++)
        {
            if (expression[i] == ' ')
            {
                /* whitespace */
                continue;
            }
            else
            {
                std::string word;

                /* Get the next word in expression string */
                while ((i < expression.length()) && (expression[i] != ' '))
                {
                    word.push_back(expression[i++]);
                }

                if (word == "_OR_" || word == "OR")
                {
                    /* OR and AND has more precedence than other operators
                     * To handle statements like "a != b or c != d"
                     * we need to execute, for above example, both '!=' before
                     * 'or' */
                    if (!operators.empty())
                    {
                        if (!evaluateExprStack(values, operators, value))
                        {
                            return false;
                        }

                        values.emplace(value);
                    }

                    operators.emplace(knob::DepexOperators::OR);
                }
                else if (word == "_AND_" || word == "AND")
                {
                    /* OR and AND has more precedence than other operators
                     * To handle statements like "a == b and c == d"
                     * we need to execute, for above example, both '==' before
                     * 'and' */
                    if (!operators.empty())
                    {
                        if (!evaluateExprStack(values, operators, value))
                        {
                            return false;
                        }

                        values.emplace(value);
                    }

                    operators.emplace(knob::DepexOperators::AND);
                }
                else if (word == "_LTE_")
                {
                    operators.emplace(knob::DepexOperators::LTE);
                }
                else if (word == "_LT_")
                {
                    operators.emplace(knob::DepexOperators::LT);
                }
                else if (word == "_GTE_")
                {
                    operators.emplace(knob::DepexOperators::GTE);
                }
                else if (word == "_GT_")
                {
                    operators.emplace(knob::DepexOperators::GT);
                }
                else if (word == "_NEQ_")
                {
                    operators.emplace(knob::DepexOperators::NEQ);
                }
                else if (word == "_EQU_")
                {
                    operators.emplace(knob::DepexOperators::EQU);
                }
                else if (word == "%")
                {
                    operators.emplace(knob::DepexOperators::MODULO);
                }
                else
                {
                    /* Handle 'Sif(', 'Gif(', 'Dif(' and '('
                     * by taking the inner/sub expression and evaluating it */
                    if (word.back() == '(')
                    {
                        if (!getSubExpression(expression, subExpression, i))
                            break;

                        if (!evaluateExpression(subExpression, value))
                            break;
                    }
                    else if (word == "_LIST_")
                    {
                        if (!getListExpression(expression, subExpression, i))
                            break;

                        --i;

                        if (!evaluateExpression(subExpression, value))
                            break;
                    }
                    else if (word == "NOT")
                    {
                        if (!getNotValue(expression, i, value))
                            break;
                    }
                    else if (isNumber(word) || isHexNotation(word))
                    {
                        try
                        {
                            value = std::stoi(word);
                        }
                        catch (const std::exception& ex)
                        {
                            phosphor::logging::log<
                                phosphor::logging::level::ERR>(ex.what());
                            return false;
                        }
                    }
                    else
                    {
                        if (!getValue(word, value))
                            break;
                    }

                    values.emplace(value);
                }
            }
        }

        if (i == expression.length())
        {
            if (evaluateExprStack(values, operators, output))
            {
                return true;
            }
        }

        return false;
    }

  private:
    /* To store all 'knob's in 'biosknobs' */
    std::vector<knob::knob>& mKnobs;

    /* To store all bad 'depex' expression */
    std::vector<std::string> mError;
};

class Xml
{
  public:
    Xml(const char* filePath) : mDepex(std::make_unique<Depex>(mKnobs))
    {
        if (!getKnobs(filePath))
        {
            std::string error =
                "Unable to get knobs in file: " + std::string(filePath);
            throw std::runtime_error(error);
        }
    }

    /* Fill Bios table with all 'knob's which have output of 'depex' expression
     * as 'true' */
    bool getBaseTable(bios::BiosBaseTableType& baseTable)
    {
        baseTable.clear();

        for (auto& knob : mKnobs)
        {
            if (knob.depex)
            {
                std::string text =
                    "xyz.openbmc_project.BIOSConfig.Manager.BoundType.OneOf";
                bios::OptionTypeVector options;

                for (auto& option : knob.options)
                {
                    options.emplace_back(text, option.value, option.text);
                }

                bios::BiosBaseTableTypeEntry baseTableEntry = std::make_tuple(
                    "xyz.openbmc_project.BIOSConfig.Manager.AttributeType."
                    "Enumeration",
                    false, knob.promptStr, knob.descriptionStr, "./",
                    knob.currentValStr, knob.defaultStr, options);

                baseTable.emplace(knob.nameStr, baseTableEntry);
            }
        }

        if (!baseTable.empty())
        {
            return true;
        }

        return false;
    }

    /* Execute all 'depex' expression */
    bool doDepexCompute()
    {
        mDepex->compute();

        if (mDepex->getErrorCount())
        {
            mDepex->printError();
            return false;
        }

        return true;
    }

  private:
    /* Get 'option' */
    void getOption(tinyxml2::XMLElement* pOption)
    {
        if (pOption)
        {
            std::string valueStr;
            std::string textStr;

            if (pOption->Attribute("text"))
                valueStr = pOption->Attribute("text");

            if (pOption->Attribute("value"))
                textStr = pOption->Attribute("value");

            mKnobs.back().options.emplace_back(pOption->Attribute("text"),
                                               pOption->Attribute("value"));
        }
    }

    /* Get 'options' */
    void getOptions(tinyxml2::XMLElement* pKnob)
    {
        uint16_t reserveCnt = 0;

        /* Get node options inside knob */
        tinyxml2::XMLElement* pOptions = pKnob->FirstChildElement("options");

        if (pOptions)
        {
            for (tinyxml2::XMLElement* pOption =
                     pOptions->FirstChildElement("option");
                 pOption; pOption = pOption->NextSiblingElement("option"))
            {
                ++reserveCnt;
            }

            mKnobs.back().options.reserve(reserveCnt);

            /* Loop through all option inside options */
            for (tinyxml2::XMLElement* pOption =
                     pOptions->FirstChildElement("option");
                 pOption; pOption = pOption->NextSiblingElement("option"))
            {
                getOption(pOption);
            }
        }
    }

    /* Get 'knob' */
    void getKnob(tinyxml2::XMLElement* pKnob)
    {
        if (pKnob)
        {
            int currentVal = 0;
            std::string nameStr;
            std::string currentValStr;
            std::string descriptionStr;
            std::string defaultStr;
            std::string depexStr;
            std::string promptStr;
            std::string setupTypeStr;

            if (!pKnob->Attribute("name") || !pKnob->Attribute("CurrentVal"))
            {
                return;
            }

            nameStr = pKnob->Attribute("name");
            currentValStr = pKnob->Attribute("CurrentVal");
            std::stringstream ss;
            ss << std::hex << currentValStr;
            if (ss.good())
            {
                ss >> currentVal;
            }
            else
            {
                std::string error = "Invalid hex value input " + currentValStr +
                                    " for " + nameStr + "\n";
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    error.c_str());
                return;
            }
            if (pKnob->Attribute("description"))
                descriptionStr = pKnob->Attribute("description");

            if (pKnob->Attribute("default"))
                defaultStr = pKnob->Attribute("default");

            if (pKnob->Attribute("depex"))
                depexStr = pKnob->Attribute("depex");

            if (pKnob->Attribute("prompt"))
                promptStr = pKnob->Attribute("prompt");

            if (pKnob->Attribute("setupType"))
                setupTypeStr = pKnob->Attribute("setupType");

            mKnobs.emplace_back(nameStr, currentValStr, currentVal,
                                descriptionStr, defaultStr, promptStr, depexStr,
                                setupTypeStr);

            getOptions(pKnob);
        }
    }

    /* Get 'biosknobs' */
    bool getKnobs(const char* biosXmlFilePath)
    {
        uint16_t reserveCnt = 0;

        mKnobs.clear();

        tinyxml2::XMLDocument biosXml;

        /* Load the XML file into the Doc instance */
        biosXml.LoadFile(biosXmlFilePath);

        /* Get 'SYSTEM' */
        tinyxml2::XMLElement* pRootElement = biosXml.RootElement();
        if (pRootElement)
        {
            /* Get 'biosknobs' inside 'SYSTEM' */
            tinyxml2::XMLElement* pBiosknobs =
                pRootElement->FirstChildElement("biosknobs");
            if (pBiosknobs)
            {
                for (tinyxml2::XMLElement* pKnob =
                         pBiosknobs->FirstChildElement("knob");
                     pKnob; pKnob = pKnob->NextSiblingElement("knob"))
                {
                    ++reserveCnt;
                }

                /* reserve before emplace_back will avoids realloc(s) */
                mKnobs.reserve(reserveCnt);

                for (tinyxml2::XMLElement* pKnob =
                         pBiosknobs->FirstChildElement("knob");
                     pKnob; pKnob = pKnob->NextSiblingElement("knob"))
                {
                    getKnob(pKnob);
                }
            }
        }

        if (!mKnobs.empty())
        {
            return true;
        }

        return false;
    }

  private:
    /* To store all 'knob's in 'biosknobs' */
    std::vector<knob::knob> mKnobs;

    /* Object of Depex class to compute 'depex' expression */
    std::unique_ptr<Depex> mDepex;
};
} // namespace bios
