#include "device_holder.h"

#include "barrier/generic_barrier.h"
#include "platform_scale/generic_platform_scale.h"
#include "sound_column/generic_sound_column.h"
#include "vidicon/generic_vidicon.h"
#include "vidicon/barrier_vidicon.h"

namespace zsy
{
    void DeviceHolder::initBarriers(std::vector<BarrierProperties> &configs)
    {
        for (auto &config: configs)
        {
            barriers.emplace(config.sn, std::make_shared<GenericBarrier>(config));
            auto &map = relation[config.sn];
            map.emplace("platformScale", config.platformScale);
            map.emplace("soundColumn", config.soundColumn);
            map.emplace("vidicon", config.vidicon);
        }
    }

    void DeviceHolder::initPlatformScales(std::vector<PlatformScaleProperties> &configs)
    {
        for (auto &config: configs)
        {
            platformScales.emplace(config.sn, std::make_shared<GenericPlatformScale>(config));
        }
    }

    void DeviceHolder::initSoundColumns(std::vector<SoundColumnProperties> &configs)
    {
        for (auto &config: configs)
        {
            soundColumns.emplace(config.sn, std::make_shared<GenericSoundColumn>(config));
        }
    }

    void DeviceHolder::initVidicons(std::vector<VidiconProperties> &configs)
    {
        for (auto &config: configs)
        {
            if (config.type == 0)
            {
                vidicons.emplace(config.sn, std::make_shared<GenericVidicon>(config));
            } else
            {
                vidicons.emplace(config.sn, std::make_shared<BarrierVidicon>(config));
            }
        }
    }

    DeviceHolder::DeviceHolder(const nlohmann::json &config)
    {
        LOGGER_INFO("正在初始化设备...");
        auto deviceConfig = config.get<DeviceConfig>();
        initBarriers(deviceConfig.barriers);
        initPlatformScales(deviceConfig.platformScales);
        initSoundColumns(deviceConfig.soundColumns);
        initVidicons(deviceConfig.vidicons);
        LOGGER_INFO("设备初始化完成");
    }

    std::shared_ptr<Barrier> DeviceHolder::getBarrier(const std::string &barrier_sn)
    {
        return barriers.contains(barrier_sn) ? barriers.at(barrier_sn) : nullptr;
    }

    std::shared_ptr<PlatformScale> DeviceHolder::getPlatformScale(const std::string &barrier_sn)
    {
        if (!relation.contains(barrier_sn)) return nullptr;
        auto map = relation.at(barrier_sn);
        if (!map.contains("platformScale")) return nullptr;
        auto sn = map.at("platformScale");
        return platformScales.contains(sn) ? platformScales.at(sn) : nullptr;
    }

    std::shared_ptr<SoundColumn> DeviceHolder::getSoundColumn(const std::string &barrier_sn)
    {
        if (!relation.contains(barrier_sn)) return nullptr;
        auto map = relation.at(barrier_sn);
        if (!map.contains("soundColumn")) return nullptr;
        auto sn = map.at("soundColumn");
        return soundColumns.contains(sn) ? soundColumns.at(sn) : nullptr;
    }

    std::shared_ptr<Vidicon> DeviceHolder::getVidicon(const std::string &barrier_sn)
    {
        if (!relation.contains(barrier_sn)) return nullptr;
        auto map = relation.at(barrier_sn);
        if (!map.contains("vidicon")) return nullptr;
        auto sn = map.at("vidicon");
        return vidicons.contains(sn) ? vidicons.at(sn) : nullptr;
    }
} // zsy