/*
// Copyright (c) 2018 Intel Corporation
//
// 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 "util.hpp"

#include "conf.hpp"

#include <cstdint>
#include <iostream>
#include <map>
#include <string>

namespace pid_control
{

void debugPrint(const std::map<std::string, conf::SensorConfig>& sensorConfig,
                const std::map<int64_t, conf::PIDConf>& zoneConfig,
                const std::map<int64_t, conf::ZoneConfig>& zoneDetailsConfig)
{
    if constexpr (!conf::DEBUG)
    {
        return;
    }
    // print sensor config
    std::cout << "sensor config:\n";
    std::cout << "{\n";
    for (const auto& pair : sensorConfig)
    {
        std::cout << "\t{" << pair.first << ",\n\t\t{";
        std::cout << pair.second.type << ", ";
        std::cout << pair.second.readPath << ", ";
        std::cout << pair.second.writePath << ", ";
        std::cout << pair.second.min << ", ";
        std::cout << pair.second.max << ", ";
        std::cout << pair.second.timeout << ", ";
        std::cout << pair.second.unavailableAsFailed << "},\n\t},\n";
    }
    std::cout << "}\n\n";
    std::cout << "ZoneDetailsConfig\n";
    std::cout << "{\n";
    for (const auto& zone : zoneDetailsConfig)
    {
        std::cout << "\t{" << zone.first << ",\n";
        std::cout << "\t\t{" << zone.second.minThermalOutput << ", ";
        std::cout << zone.second.failsafePercent << "}\n\t},\n";
    }
    std::cout << "}\n\n";
    std::cout << "ZoneConfig\n";
    std::cout << "{\n";
    for (const auto& zone : zoneConfig)
    {
        std::cout << "\t{" << zone.first << "\n";
        for (const auto& pidconf : zone.second)
        {
            std::cout << "\t\t{" << pidconf.first << ",\n";
            std::cout << "\t\t\t{" << pidconf.second.type << ",\n";
            std::cout << "\t\t\t{";
            for (const auto& input : pidconf.second.inputs)
            {
                std::cout << "\n\t\t\t" << input.name;
                if (input.convertTempToMargin)
                {
                    std::cout << "[" << input.convertMarginZero << "]";
                }
                std::cout << ",\n";
            }
            std::cout << "\t\t\t}\n";
            std::cout << "\t\t\t" << pidconf.second.setpoint << ",\n";
            std::cout << "\t\t\t{" << pidconf.second.pidInfo.ts << ",\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.proportionalCoeff
                      << ",\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.integralCoeff
                      << ",\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.feedFwdOffset
                      << ",\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.feedFwdGain
                      << ",\n";
            std::cout << "\t\t\t{" << pidconf.second.pidInfo.integralLimit.min
                      << "," << pidconf.second.pidInfo.integralLimit.max
                      << "},\n";
            std::cout << "\t\t\t{" << pidconf.second.pidInfo.outLim.min << ","
                      << pidconf.second.pidInfo.outLim.max << "},\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.slewNeg << ",\n";
            std::cout << "\t\t\t" << pidconf.second.pidInfo.slewPos << ",\n";
            std::cout << "\t\t\t}\n\t\t}\n";
        }
        std::cout << "\t},\n";
    }
    std::cout << "}\n\n";
}

std::vector<conf::SensorInput>
    spliceInputs(const std::vector<std::string>& inputNames,
                 const std::vector<double>& inputTempToMargin,
                 const std::vector<std::string>& missingAcceptableNames)
{
    std::vector<conf::SensorInput> results;

    // Default to TempToMargin and MissingIsAcceptable disabled
    for (const auto& inputName : inputNames)
    {
        conf::SensorInput newInput{
            inputName, std::numeric_limits<double>::quiet_NaN(), false, false};

        results.emplace_back(newInput);
    }

    size_t resultSize = results.size();
    size_t marginSize = inputTempToMargin.size();

    for (size_t index = 0; index < resultSize; ++index)
    {
        // If fewer doubles than strings, and vice versa, ignore remainder
        if (index >= marginSize)
        {
            break;
        }

        // Both vectors have this index, combine both into SensorInput
        results[index].convertMarginZero = inputTempToMargin[index];
        results[index].convertTempToMargin = true;
    }

    std::set<std::string> acceptableSet;

    // Copy vector to set, to avoid O(n^2) runtime below
    for (const auto& name : missingAcceptableNames)
    {
        acceptableSet.emplace(name);
    }

    // Flag missingIsAcceptable true if name found in that set
    for (auto& result : results)
    {
        if (acceptableSet.find(result.name) != acceptableSet.end())
        {
            result.missingIsAcceptable = true;
        }
    }

    return results;
}

std::vector<std::string>
    splitNames(const std::vector<conf::SensorInput>& sensorInputs)
{
    std::vector<std::string> results;

    for (const auto& sensorInput : sensorInputs)
    {
        results.emplace_back(sensorInput.name);
    }

    return results;
}

} // namespace pid_control
