/**
 * 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("checkHysterWithSetpt");
    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
