#include "device_group.h"

#include "loadometer/general_loadometer.h"
#include "spkbox/general_spkbox.h"
#include "vidicon/hk_vidicon.h"
#include "vidicon/gwytj_vidicon.h"
#include "ytj/ytj.h"

namespace zsy
{
    DeviceGroup::DeviceGroup(const DeviceGroupConfig &config)
        : config(config)
    {
        for (const auto &vidicon_config: config.vidicon_config())
        {
            if (vidicon_config.vidicon_type() == VidiconConfig_VidiconType_HK)
            {
                vidicons[vidicon_config.sn()] = std::make_shared<HKVidicon>(vidicon_config);
            } else if (vidicon_config.vidicon_type() == VidiconConfig_VidiconType_YTJ)
            {
                vidicons[vidicon_config.sn()] = std::make_shared<GWYTJVidicon>(vidicon_config);
            }
        }
        for (const auto &spkbox_config: config.spkbox_config())
        {
            spkboxes[spkbox_config.sn()] = std::make_shared<GeneralSpkbox>(spkbox_config);
        }
        loadometer = std::make_shared<GeneralLoadometer>(config.loadometer_config());
        for (const auto &ytj_config: config.ytj_config())
        {
            barriers[ytj_config.sn()] = std::make_shared<Ytj>(ytj_config);
        }
        for (const auto &device_association: config.device_associations())
        {
            associations[device_association.barrier_sn()][DeviceType::BARRIER] = device_association.barrier_sn();
            associations[device_association.barrier_sn()][DeviceType::VIDICON] = device_association.vidicon_sn();
            associations[device_association.barrier_sn()][DeviceType::SPKBOX] = device_association.spkbox_sn();
            associations[device_association.barrier_sn()][DeviceType::LOADOMETER] = device_association.loadometer_sn();
        }
    }

    std::shared_ptr<Vidicon> DeviceGroup::getVidicon(const std::string &barrierSn) const
    {
        if (associations.contains(barrierSn))
        {
            if (auto vidicon_sn = associations.at(barrierSn).at(DeviceType::VIDICON); vidicons.contains(vidicon_sn))
            {
                return vidicons.at(vidicon_sn);
            }
        }
        return nullptr;
    }

    std::shared_ptr<Spkbox> DeviceGroup::getSpkbox(const std::string &barrierSn) const
    {
        if (associations.contains(barrierSn))
        {
            if (auto spkbox_sn = associations.at(barrierSn).at(DeviceType::SPKBOX); spkboxes.contains(spkbox_sn))
            {
                return spkboxes.at(spkbox_sn);
            }
        }
        return nullptr;
    }

    std::shared_ptr<Loadometer> DeviceGroup::getLoadometer(const std::string &barrierSn) const
    {
        if (associations.contains(barrierSn))
        {
            if (auto loadometer_sn = associations.at(barrierSn).at(DeviceType::LOADOMETER); loadometer_sn == loadometer->sn())
            {
                return loadometer;
            }
        }
        return nullptr;
    }

    std::shared_ptr<Ytj> DeviceGroup::getBarrier(const std::string &barrierSn) const
    {
        if (barriers.contains(barrierSn))
        {
            return barriers.at(barrierSn);
        }
        return nullptr;
    }
} // zsy