/**
 * Copyright 2019 Google Inc.
 *
 * 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.
 */

#include "pid/buildjson.hpp"

#include "conf.hpp"
#include "util.hpp"

#include <nlohmann/json.hpp>

#include <iostream>
#include <limits>
#include <map>
#include <tuple>

namespace pid_control
{

using json = nlohmann::json;

namespace conf
{

void from_json(const json& j, conf::ControllerInfo& c)
{
    std::vector<std::string> inputNames;
    std::vector<std::string> missingAcceptableNames;

    j.at("type").get_to(c.type);
    j.at("inputs").get_to(inputNames);
    j.at("setpoint").get_to(c.setpoint);

    std::vector<double> inputTempToMargin;

    auto findTempToMargin = j.find("tempToMargin");
    if (findTempToMargin != j.end())
    {
        findTempToMargin->get_to(inputTempToMargin);
    }

    auto findMissingAcceptable = j.find("missingIsAcceptable");
    if (findMissingAcceptable != j.end())
    {
        findMissingAcceptable->get_to(missingAcceptableNames);
    }

    c.inputs =
        spliceInputs(inputNames, inputTempToMargin, missingAcceptableNames);

    /* TODO: We need to handle parsing other PID controller configurations.
     * We can do that by checking for different keys and making the decision
     * accordingly.
     */
    auto p = j.at("pid");

    auto checkHysterWithSetpt = p.find("checkHysteresisWithSetpoint");
    auto positiveHysteresis = p.find("positiveHysteresis");
    auto negativeHysteresis = p.find("negativeHysteresis");
    auto derivativeCoeff = p.find("derivativeCoeff");
    auto checkHysterWithSetptValue = false;
    auto positiveHysteresisValue = 0.0;
    auto negativeHysteresisValue = 0.0;
    auto derivativeCoeffValue = 0.0;
    if (checkHysterWithSetpt != p.end())
    {
        checkHysterWithSetpt->get_to(checkHysterWithSetptValue);
    }
    if (positiveHysteresis != p.end())
    {
        positiveHysteresis->get_to(positiveHysteresisValue);
    }
    if (negativeHysteresis != p.end())
    {
        negativeHysteresis->get_to(negativeHysteresisValue);
    }
    if (derivativeCoeff != p.end())
    {
        derivativeCoeff->get_to(derivativeCoeffValue);
    }

    auto failSafePercent = j.find("FailSafePercent");
    auto failSafePercentValue = 0;
    if (failSafePercent != j.end())
    {
        failSafePercent->get_to(failSafePercentValue);
    }
    c.failSafePercent = failSafePercentValue;

    if (c.type != "stepwise")
    {
        p.at("samplePeriod").get_to(c.pidInfo.ts);
        p.at("proportionalCoeff").get_to(c.pidInfo.proportionalCoeff);
        p.at("integralCoeff").get_to(c.pidInfo.integralCoeff);
        p.at("feedFwdOffsetCoeff").get_to(c.pidInfo.feedFwdOffset);
        p.at("feedFwdGainCoeff").get_to(c.pidInfo.feedFwdGain);
        p.at("integralLimit_min").get_to(c.pidInfo.integralLimit.min);
        p.at("integralLimit_max").get_to(c.pidInfo.integralLimit.max);
        p.at("outLim_min").get_to(c.pidInfo.outLim.min);
        p.at("outLim_max").get_to(c.pidInfo.outLim.max);
        p.at("slewNeg").get_to(c.pidInfo.slewNeg);
        p.at("slewPos").get_to(c.pidInfo.slewPos);

        // Unlike other coefficients, treat derivativeCoeff as an optional
        // parameter, as support for it is fairly new, to avoid breaking
        // existing configurations in the field that predate it.
        c.pidInfo.positiveHysteresis = positiveHysteresisValue;
        c.pidInfo.negativeHysteresis = negativeHysteresisValue;
        c.pidInfo.derivativeCoeff = derivativeCoeffValue;
        c.pidInfo.checkHysterWithSetpt = checkHysterWithSetptValue;
    }
    else
    {
        p.at("samplePeriod").get_to(c.stepwiseInfo.ts);
        p.at("isCeiling").get_to(c.stepwiseInfo.isCeiling);

        for (size_t i = 0; i < ec::maxStepwisePoints; i++)
        {
            c.stepwiseInfo.reading[i] =
                std::numeric_limits<double>::quiet_NaN();
            c.stepwiseInfo.output[i] = std::numeric_limits<double>::quiet_NaN();
        }

        auto reading = p.find("reading");
        if (reading != p.end())
        {
            auto r = p.at("reading");
            for (size_t i = 0; i < ec::maxStepwisePoints; i++)
            {
                auto n = r.find(std::to_string(i));
                if (n != r.end())
                {
                    r.at(std::to_string(i)).get_to(c.stepwiseInfo.reading[i]);
                }
            }
        }

        auto output = p.find("output");
        if (output != p.end())
        {
            auto o = p.at("output");
            for (size_t i = 0; i < ec::maxStepwisePoints; i++)
            {
                auto n = o.find(std::to_string(i));
                if (n != o.end())
                {
                    o.at(std::to_string(i)).get_to(c.stepwiseInfo.output[i]);
                }
            }
        }

        c.stepwiseInfo.positiveHysteresis = positiveHysteresisValue;
        c.stepwiseInfo.negativeHysteresis = negativeHysteresisValue;
    }
}

} // namespace conf

inline void getCycleTimeSetting(const auto& zone, const int id,
                                const std::string& attributeName,
                                uint64_t& value)
{
    auto findAttributeName = zone.find(attributeName);
    if (findAttributeName != zone.end())
    {
        uint64_t tmpAttributeValue = 0;
        findAttributeName->get_to(tmpAttributeValue);
        if (tmpAttributeValue >= 1)
        {
            value = tmpAttributeValue;
        }
        else
        {
            std::cerr << "Zone " << id << ": " << attributeName
                      << " is invalid. Use default " << value << " ms\n";
        }
    }
    else
    {
        std::cerr << "Zone " << id << ": " << attributeName
                  << " cannot find setting. Use default " << value << " ms\n";
    }
}

std::pair<std::map<int64_t, conf::PIDConf>, std::map<int64_t, conf::ZoneConfig>>
    buildPIDsFromJson(const json& data)
{
    // zone -> pids
    std::map<int64_t, conf::PIDConf> pidConfig;
    // zone -> configs
    std::map<int64_t, conf::ZoneConfig> zoneConfig;

    /* TODO: if zones is empty, that's invalid. */
    auto zones = data["zones"];
    for (const auto& zone : zones)
    {
        int64_t id;
        conf::PIDConf thisZone;
        conf::ZoneConfig thisZoneConfig;

        /* TODO: using at() throws a specific exception we can catch */
        id = zone["id"];
        thisZoneConfig.minThermalOutput = zone["minThermalOutput"];
        thisZoneConfig.failsafePercent = zone["failsafePercent"];

        getCycleTimeSetting(zone, id, "cycleIntervalTimeMS",
                            thisZoneConfig.cycleTime.cycleIntervalTimeMS);
        getCycleTimeSetting(zone, id, "updateThermalsTimeMS",
                            thisZoneConfig.cycleTime.updateThermalsTimeMS);

        bool accumulateSetPoint = false;
        auto findAccSetPoint = zone.find("accumulateSetPoint");
        if (findAccSetPoint != zone.end())
        {
            findAccSetPoint->get_to(accumulateSetPoint);
        }
        thisZoneConfig.accumulateSetPoint = accumulateSetPoint;

        auto pids = zone["pids"];
        for (const auto& pid : pids)
        {
            auto name = pid["name"];
            auto item = pid.get<conf::ControllerInfo>();

            if (thisZone.find(name) != thisZone.end())
            {
                std::cerr << "Warning: zone " << id
                          << " have the same pid name " << name << std::endl;
            }

            thisZone[name] = item;
        }

        pidConfig[id] = thisZone;
        zoneConfig[id] = thisZoneConfig;
    }

    return std::make_pair(pidConfig, zoneConfig);
}

} // namespace pid_control
