/**
 * 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 <iostream>

/* Configuration. */
#include "conf.hpp"

#include "dbus/dbuspassive.hpp"
#include "interfaces.hpp"
#include "notimpl/readonly.hpp"
#include "notimpl/writeonly.hpp"
#include "sensors/builder.hpp"
#include "sensors/manager.hpp"
#include "sensors/host.hpp"
#include "sensors/pluggable.hpp"
#include "sysfs/sysfsread.hpp"
#include "sysfs/sysfswrite.hpp"
#include "util.hpp"

static constexpr bool deferSignals = true;

std::shared_ptr<SensorManager> BuildSensors(
    const std::map<std::string, struct sensor>& config)
{
    auto mgmr = std::make_shared<SensorManager>();
    auto& HostSensorBus = mgmr->getHostBus();
    auto& PassiveListeningBus = mgmr->getPassiveBus();

    for (auto& it : config)
    {
        std::unique_ptr<ReadInterface> ri;
        std::unique_ptr<WriteInterface> wi;

        std::string name = it.first;
        const struct sensor* info = &it.second;

        std::cerr << "Sensor: " << name << " " << info->type << " ";
        std::cerr << info->readpath << " " << info->writepath << "\n";

        IOInterfaceType rtype = GetReadInterfaceType(info->readpath);
        IOInterfaceType wtype = GetWriteInterfaceType(info->writepath);

        // fan sensors can be ready any way and written others.
        // fan sensors are the only sensors this is designed to write.
        // Nothing here should be write-only, although, in theory a fan could be.
        // I'm just not sure how that would fit together.
        // TODO(venture): It should check with the ObjectMapper to check if
        // that sensor exists on the Dbus.
        switch (rtype)
        {
            case IOInterfaceType::DBUSPASSIVE:
                ri = std::make_unique<DbusPassive>(
                         PassiveListeningBus,
                         info->type,
                         name);
                break;
            case IOInterfaceType::EXTERNAL:
                // These are a special case for read-only.
                break;
            case IOInterfaceType::SYSFS:
                ri = std::make_unique<SysFsRead>(info->readpath);
                break;
            default:
                ri = std::make_unique<WriteOnly>();
                break;
        }

        if (info->type == "fan")
        {
            switch (wtype)
            {
                case IOInterfaceType::SYSFS:
                    if (info->max > 0)
                    {
                        wi = std::make_unique<SysFsWritePercent>(
                                 info->writepath,
                                 info->min,
                                 info->max);
                    }
                    else
                    {
                        wi = std::make_unique<SysFsWrite>(
                                 info->writepath,
                                 info->min,
                                 info->max);
                    }

                    break;
                default:
                    wi = std::make_unique<ReadOnlyNoExcept>();
                    break;
            }

            auto sensor = std::make_unique<PluggableSensor>(
                              name,
                              info->timeout,
                              std::move(ri),
                              std::move(wi));
            mgmr->addSensor(info->type, name, std::move(sensor));
        }
        else if (info->type == "temp" || info->type == "margin")
        {
            // These sensors are read-only, but only for this application
            // which only writes to fan sensors.
            std::cerr << info->type << " readpath: " << info->readpath << "\n";

            if (IOInterfaceType::EXTERNAL == rtype)
            {
                std::cerr << "Creating HostSensor: " << name
                          << " path: " << info->readpath << "\n";

                /*
                 * The reason we handle this as a HostSensor is because it's
                 * not quite pluggable; but maybe it could be.
                 */
                auto sensor = HostSensor::CreateTemp(
                                  name,
                                  info->timeout,
                                  HostSensorBus,
                                  info->readpath.c_str(),
                                  deferSignals);
                mgmr->addSensor(info->type, name, std::move(sensor));
            }
            else
            {
                wi = std::make_unique<ReadOnlyNoExcept>();
                auto sensor = std::make_unique<PluggableSensor>(
                                  name,
                                  info->timeout,
                                  std::move(ri),
                                  std::move(wi));
                mgmr->addSensor(info->type, name, std::move(sensor));
            }
        }
    }

    return mgmr;
}

