/**
 * 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 <nlohmann/json.hpp>

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

namespace pid_control
{

using json = nlohmann::json;

namespace conf
{
void from_json(const json& j, conf::ControllerInfo& c)
{
    j.at("type").get_to(c.type);
    j.at("inputs").get_to(c.inputs);
    j.at("setpoint").get_to(c.setpoint);

    /* 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 positiveHysteresis = p.find("positiveHysteresis");
    auto negativeHysteresis = p.find("negativeHysteresis");
    auto derivativeCoeff = p.find("derivativeCoeff");
    auto positiveHysteresisValue = 0.0;
    auto negativeHysteresisValue = 0.0;
    auto derivativeCoeffValue = 0.0;
    if (positiveHysteresis != p.end())
    {
        positiveHysteresis->get_to(positiveHysteresisValue);
    }
    if (negativeHysteresis != p.end())
    {
        negativeHysteresis->get_to(negativeHysteresisValue);
    }
    if (derivativeCoeff != p.end())
    {
        derivativeCoeff->get_to(derivativeCoeffValue);
    }

    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;
    }
    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);

        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
