/**
 * \file    Mimic_Enumeration.hpp
 * \author  Silvan Murer
 * \date    13 October 2022
 *
 * \brief   Enumeration class of genSDK GF implementation, based on Mimic_Node
 */

#include "features/Mimic_Enumeration.hpp"
#include "Mimic_Exception.hpp"

#define GENICAM_NO_AUTO_IMPLIB
#include "GenICam.h"

#include <memory>
#include <string>

using namespace GenApi;

namespace mimic {

    Mimic_Enumeration::Mimic_Enumeration() : Mimic_Node() { type = Type_e::ENUMERATION; };
    Mimic_Enumeration::Mimic_Enumeration(GenApi_3_4::INode* node) : Mimic_Node(node) { type = Type_e::ENUMERATION; };
    Mimic_Enumeration::~Mimic_Enumeration() { };

    std::variant<int64_t, double, bool, std::string> Mimic_Enumeration::getVariant(std::string name)
    {
        return getValue();
    };
    void Mimic_Enumeration::setVariant(std::string name, std::variant<int64_t, double, bool, std::string> value)
    {
        try {
            setValue(std::get<std::string>(value));
        }
        catch (std::bad_variant_access const& e) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " is of type Enumeration! " + e.what(), -650);
        }
        catch (...) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " read failed!", -610);
        }

    }

    std::string Mimic_Enumeration::getValue()
    {
        if (!IsImplemented(node) || !IsAvailable(node) || !IsReadable(node)) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " is not readable!", -600);
        }
        try {
            return std::string(dynamic_cast<IEnumeration*>(node)->GetCurrentEntry()->GetSymbolic().c_str());
        }
        catch (...) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " read failed!", -610);
        }
    }
    void Mimic_Enumeration::setValue(std::string value)
    {
        if (!IsImplemented(node) || !IsAvailable(node) || !IsWritable(node)) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " is not writable!", -600);
        }
        try {
            IEnumeration* enumNode = dynamic_cast<IEnumeration*>(node);
            return enumNode->SetIntValue(enumNode->GetEntryByName(value.c_str())->GetValue());
        }
        catch (...) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " write failed!", -610);
        }
    }

    std::vector<std::string> Mimic_Enumeration::getListOfValidValue()
    {
        try {
            std::vector<std::string> entryList = std::vector<std::string>();
            IEnumeration* enumNode = dynamic_cast<IEnumeration*>(node);
            NodeList_t nodeList;
            enumNode->GetEntries(nodeList);
            for (auto entry : nodeList) {
                entryList.push_back(std::string(entry->GetDisplayName().c_str()));
            }
            return entryList;
        }
        catch (...) {
            throw Mimic_Access_Exception(std::string("Node ") + node->GetName().c_str() + " write failed!", -610);
        }
    }

} /* namespace genSDK */
