/**
 * 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 "config.h"

#include "conf.hpp"
#include "interfaces.hpp"
#include "pid/builder.hpp"
#include "pid/builderconfig.hpp"
#include "pid/pidthread.hpp"
#include "pid/zone.hpp"
#include "sensors/builder.hpp"
#include "sensors/builderconfig.hpp"
#include "sensors/manager.hpp"
#include "threads/busthread.hpp"
#include "util.hpp"

#include <getopt.h>

#include <chrono>
#include <experimental/any>
#include <iostream>
#include <map>
#include <memory>
#include <mutex> /* not yet used. */
#include <sdbusplus/bus.hpp>
#include <thread>
#include <unordered_map>
#include <vector>

#if CONFIGURE_DBUS
#include "dbus/dbusconfiguration.hpp"
#endif

/* The YAML converted sensor list. */
extern std::map<std::string, struct sensor> SensorConfig;
/* The YAML converted PID list. */
extern std::map<int64_t, PIDConf> ZoneConfig;
/* The YAML converted Zone configuration. */
extern std::map<int64_t, struct zone> ZoneDetailsConfig;

int main(int argc, char* argv[])
{
    int rc = 0;
    int c;
    std::string configPath = "";

    while (1)
    {
        // clang-format off
        static struct option long_options[] = {
            {"conf", required_argument, 0, 'c'},
            {0, 0, 0, 0}
        };
        // clang-format on

        int option_index = 0;
        c = getopt_long(argc, argv, "c:", long_options, &option_index);

        if (c == -1)
        {
            break;
        }

        switch (c)
        {
            case 'c':
                configPath = std::string{optarg};
                break;
            default:
                /* skip garbage. */
                continue;
        }
    }

    auto ModeControlBus = sdbusplus::bus::new_default();
#if CONFIGURE_DBUS
    {
        dbus_configuration::init(ModeControlBus);
    }
#endif
    SensorManager mgmr;
    std::unordered_map<int64_t, std::unique_ptr<PIDZone>> zones;

    // Create a manager for the ModeBus because we own it.
    static constexpr auto modeRoot = "/xyz/openbmc_project/settings/fanctrl";
    sdbusplus::server::manager::manager(ModeControlBus, modeRoot);

    /*
     * When building the sensors, if any of the dbus passive ones aren't on the
     * bus, it'll fail immediately.
     */
    if (configPath.length() > 0)
    {
        try
        {
            mgmr = BuildSensorsFromConfig(configPath);
            zones = BuildZonesFromConfig(configPath, mgmr, ModeControlBus);
        }
        catch (const std::exception& e)
        {
            std::cerr << "Failed during building: " << e.what() << "\n";
            exit(EXIT_FAILURE); /* fatal error. */
        }
    }
    else
    {
        mgmr = BuildSensors(SensorConfig);
        zones = BuildZones(ZoneConfig, ZoneDetailsConfig, mgmr, ModeControlBus);
    }

    if (0 == zones.size())
    {
        std::cerr << "No zones defined, exiting.\n";
        return rc;
    }

    /*
     * All sensors are managed by one manager, but each zone has a pointer to
     * it.
     */

    auto& HostSensorBus = mgmr.getHostBus();
    auto& PassiveListeningBus = mgmr.getPassiveBus();

    std::cerr << "Starting threads\n";

    /* TODO(venture): Ask SensorManager if we have any passive sensors. */
    struct ThreadParams p = {std::ref(PassiveListeningBus), ""};
    std::thread l(BusThread, std::ref(p));

    /* TODO(venture): Ask SensorManager if we have any host sensors. */
    static constexpr auto hostBus = "xyz.openbmc_project.Hwmon.external";
    struct ThreadParams e = {std::ref(HostSensorBus), hostBus};
    std::thread te(BusThread, std::ref(e));

    static constexpr auto modeBus = "xyz.openbmc_project.State.FanCtrl";
    struct ThreadParams m = {std::ref(ModeControlBus), modeBus};
    std::thread tm(BusThread, std::ref(m));

    std::vector<std::thread> zoneThreads;

    /* TODO(venture): This was designed to have one thread per zone, but really
     * it could have one thread for all the zones and iterate through each
     * sequentially as it goes -- and it'd probably be fast enough to do that,
     * however, a system isn't likely going to have more than a couple zones.
     * If it only has a couple zones, then this is fine.
     */
    for (auto& i : zones)
    {
        std::cerr << "pushing zone" << std::endl;
        zoneThreads.push_back(std::thread(PIDControlThread, i.second.get()));
    }

    l.join();
    te.join();
    tm.join();
    for (auto& t : zoneThreads)
    {
        t.join();
    }

    return rc;
}
