/**
 * Copyright 2017 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/builderconfig.hpp"

#include "conf.hpp"
#include "pid/builder.hpp"

#include <fstream>
#include <iostream>
#include <libconfig.h++>
#include <memory>
#include <sdbusplus/bus.hpp>
#include <string>
#include <unordered_map>

std::unordered_map<int64_t, std::unique_ptr<PIDZone>>
    BuildZonesFromConfig(const std::string& path, SensorManager& mgr,
                         sdbusplus::bus::bus& modeControlBus)
{
    using namespace libconfig;
    // zone -> pids
    std::map<int64_t, PIDConf> pidConfig;
    // zone -> configs
    std::map<int64_t, struct zone> zoneConfig;

    std::cerr << "entered BuildZonesFromConfig\n";

    Config cfg;

    /* The load was modeled after the example source provided. */
    try
    {
        cfg.readFile(path.c_str());
    }
    catch (const FileIOException& fioex)
    {
        std::cerr << "I/O error while reading file: " << fioex.what()
                  << std::endl;
        throw;
    }
    catch (const ParseException& pex)
    {
        std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
                  << " - " << pex.getError() << std::endl;
        throw;
    }

    try
    {
        const Setting& root = cfg.getRoot();
        const Setting& zones = root["zones"];
        int count = zones.getLength();

        /* For each zone. */
        for (int i = 0; i < count; ++i)
        {
            const Setting& zoneSettings = zones[i];

            int id;
            PIDConf thisZone;
            struct zone thisZoneConfig;

            zoneSettings.lookupValue("id", id);

            thisZoneConfig.minthermalrpm = zoneSettings.lookup("minthermalrpm");
            thisZoneConfig.failsafepercent =
                zoneSettings.lookup("failsafepercent");

            const Setting& pids = zoneSettings["pids"];
            int pidCount = pids.getLength();

            for (int j = 0; j < pidCount; ++j)
            {
                const Setting& pid = pids[j];

                std::string name;
                controller_info info;

                /*
                 * Mysteriously if you use lookupValue on these, and the type
                 * is float.  It won't work right.
                 *
                 * If the configuration file value doesn't look explicitly like
                 * a float it won't let you assign it to one.
                 */
                name = pid.lookup("name").c_str();
                info.type = pid.lookup("type").c_str();
                /* set-point is only required to be set for thermal. */
                /* TODO(venture): Verify this works optionally here. */
                info.setpoint = pid.lookup("set-point");
                info.info.ts = pid.lookup("pid.sampleperiod");
                info.info.p_c = pid.lookup("pid.p_coefficient");
                info.info.i_c = pid.lookup("pid.i_coefficient");
                info.info.ff_off = pid.lookup("pid.ff_off_coefficient");
                info.info.ff_gain = pid.lookup("pid.ff_gain_coefficient");
                info.info.i_lim.min = pid.lookup("pid.i_limit.min");
                info.info.i_lim.max = pid.lookup("pid.i_limit.max");
                info.info.out_lim.min = pid.lookup("pid.out_limit.min");
                info.info.out_lim.max = pid.lookup("pid.out_limit.max");
                info.info.slew_neg = pid.lookup("pid.slew_neg");
                info.info.slew_pos = pid.lookup("pid.slew_pos");

                std::cerr << "out_lim.min: " << info.info.out_lim.min << "\n";
                std::cerr << "out_lim.max: " << info.info.out_lim.max << "\n";

                const Setting& inputs = pid["inputs"];
                int icount = inputs.getLength();

                for (int z = 0; z < icount; ++z)
                {
                    std::string v;
                    v = pid["inputs"][z].c_str();
                    info.inputs.push_back(v);
                }

                thisZone[name] = info;
            }

            pidConfig[static_cast<int64_t>(id)] = thisZone;
            zoneConfig[static_cast<int64_t>(id)] = thisZoneConfig;
        }
    }
    catch (const SettingTypeException& setex)
    {
        std::cerr << "Setting '" << setex.getPath() << "' type exception!"
                  << std::endl;
        throw;
    }
    catch (const SettingNotFoundException& snex)
    {
        std::cerr << "Setting '" << snex.getPath() << "' not found!"
                  << std::endl;
        throw;
    }

    return BuildZones(pidConfig, zoneConfig, mgr, modeControlBus);
}
