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

    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("derivativeCoeff").get_to(c.pidInfo.derivativeCoeff);
        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);

        c.pidInfo.positiveHysteresis = positiveHysteresisValue;
        c.pidInfo.negativeHysteresis = negativeHysteresisValue;
    }
    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

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"];

        auto findTimeInterval = zone.find("cycleIntervalTimeMS");
        if (findTimeInterval != zone.end())
        {
            uint64_t tmp;
            findTimeInterval->get_to(tmp);
            if (tmp != 0)
            {
                thisZoneConfig.cycleTime.cycleIntervalTimeMS = tmp;
            }
            else
            {
                std::cerr << "cycleIntervalTimeMS cannot be 0. Use default "
                          << thisZoneConfig.cycleTime.cycleIntervalTimeMS
                          << " ms\n";
            }
        }

        auto findUpdateThermalsTime = zone.find("updateThermalsTimeMS");
        if (findUpdateThermalsTime != zone.end())
        {
            uint64_t tmp;
            findUpdateThermalsTime->get_to(tmp);
            if (tmp != 0)
            {
                thisZoneConfig.cycleTime.updateThermalsTimeMS = tmp;
            }
            else
            {
                std::cerr << "updateThermalsTimeMS cannot be 0. Use default "
                          << thisZoneConfig.cycleTime.updateThermalsTimeMS
                          << " ms\n";
            }
        }

        double updateCount =
            double(thisZoneConfig.cycleTime.updateThermalsTimeMS) /
            double(thisZoneConfig.cycleTime.cycleIntervalTimeMS);

        /* Check if updateThermalsTimeMS could be divided by cycleIntervalTimeMS
         * without leaving a remainder */
        if (updateCount != std::ceil(updateCount))
        {
            std::cerr
                << "updateThermalsTimeMS cannot be divided by "
                   "cycleIntervalTimeMS without leaving a remainder. Using the "
                   "smallest integer that is not less than the result.\n";
            updateCount = std::ceil(updateCount);
        }
        thisZoneConfig.cycleTime.updateThermalsTimeMS = updateCount;

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

            thisZone[name] = item;
        }

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

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

} // namespace pid_control
