/*
 *  This file is part of CounterStrikeSharp.
 *  CounterStrikeSharp is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  CounterStrikeSharp is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with CounterStrikeSharp.  If not, see <https://www.gnu.org/licenses/>. *
 */
#include "core/globals.h"
#include "core/log.h"
#include "scripting/autonative.h"
#include "public/entity2/entitykeyvalues.h"
#include "natives_keyvalues.h"

namespace counterstrikesharp {

std::vector<CEntityKeyValues*> managed_keyvalues;

CEntityKeyValues* CreateEntityKeyValues(ScriptContext& scriptContext)
{
    auto cEntityKeyValues = new CEntityKeyValues();
    managed_keyvalues.push_back(cEntityKeyValues);

    CSSHARP_CORE_INFO("Entity Key Values: {0}", static_cast<void*>(cEntityKeyValues));

    return cEntityKeyValues;
}

void SetKeyValue(ScriptContext& scriptContext)
{
    auto handle = scriptContext.GetArgument<CEntityKeyValues*>(0);
    auto key = scriptContext.GetArgument<const char*>(1);
    auto type = scriptContext.GetArgument<KeyValuesValueType>(3);

    CSSHARP_CORE_INFO("entityId: {0}", key);
    CSSHARP_CORE_INFO("Handle: {0}", static_cast<void*>(handle));

    switch (type) {
    case KeyValuesValueType::Integer: {
        auto value = scriptContext.GetArgument<int>(2);
        handle->SetInt(key, value);
        break;
    }
    case KeyValuesValueType::String: {
        auto value = scriptContext.GetArgument<const char*>(2);
        handle->SetString(key, value);
        CSSHARP_CORE_INFO("String: {0}, {1}", key, value);
        break;
    }
    case KeyValuesValueType::Long: {
        auto value = scriptContext.GetArgument<long>(2);
        handle->SetInt64(key, value);
        break;
    }
    case KeyValuesValueType::Float: {
        auto value = scriptContext.GetArgument<float>(2);
        handle->SetFloat(key, value);
        CSSHARP_CORE_INFO("Float: {0}, {1}", key, value);
        CSSHARP_CORE_INFO("Float: {0}", handle->GetFloat(key));
        break;
    }
    case KeyValuesValueType::Color: {
        auto value = scriptContext.GetArgument<Color>(2);
        handle->SetColor(key, value);

        CSSHARP_CORE_INFO("Color: {0}, R - {1}, G - {2}, B - {3}", key, value.r(), value.g(),
                          value.b());
        break;
    }
    case KeyValuesValueType::UnsignedInteger: {
        auto value = scriptContext.GetArgument<uint32_t>(2);
        handle->SetUint(key, value);
        break;
    }
    case KeyValuesValueType::UnsignedLong: {
        auto value = scriptContext.GetArgument<uint64_t>(2);
        handle->SetUint64(key, value);
        break;
    }
    case KeyValuesValueType::Vector: {
        auto value = scriptContext.GetArgument<Vector>(2);
        handle->SetVector(key, value);
        break;
    }
    case KeyValuesValueType::QAngle: {
        auto value = scriptContext.GetArgument<QAngle>(2);
        handle->SetQAngle(key, value);
        break;
    }
    case KeyValuesValueType::Boolean: {
        auto value = scriptContext.GetArgument<bool>(2);
        handle->SetBool(key, value);
        break;
    }
    default:
        break;
    }
}

void GetKeyValue(ScriptContext& scriptContext)
{
    auto handle = scriptContext.GetArgument<CEntityKeyValues*>(0);
    auto key = scriptContext.GetArgument<const char*>(1);
    auto type = scriptContext.GetArgument<KeyValuesValueType>(2);

    switch (type) {
    case KeyValuesValueType::Integer: {
        scriptContext.SetResult(handle->GetInt(key));
        ;
        break;
    }
    case KeyValuesValueType::String: {
        scriptContext.SetResult(handle->GetString(key));
        break;
    }
    case KeyValuesValueType::Long: {
        scriptContext.SetResult(handle->GetInt64(key));
        break;
    }
    case KeyValuesValueType::Float: {
        scriptContext.SetResult(handle->GetFloat(key));
        break;
    }
    case KeyValuesValueType::Color: {
        scriptContext.SetResult(handle->GetColor(key));
        break;
    }
    case KeyValuesValueType::UnsignedInteger: {
        scriptContext.SetResult(handle->GetUint(key));
        break;
    }
    case KeyValuesValueType::UnsignedLong: {
        scriptContext.SetResult(handle->GetUint64(key));
        break;
    }
    case KeyValuesValueType::Vector: {
        scriptContext.SetResult(handle->GetVector(key));
        break;
    }
    case KeyValuesValueType::QAngle: {
        scriptContext.SetResult(handle->GetQAngle(key));
        break;
    }
    case KeyValuesValueType::Boolean: {
        scriptContext.SetResult(handle->GetBool(key));
        break;
    }
    default:
        break;
    }
}

REGISTER_NATIVES(key_values, {
    ScriptEngine::RegisterNativeHandler("CREATE_ENTITY_KEY_VALUES", CreateEntityKeyValues);
    ScriptEngine::RegisterNativeHandler("SET_KEY_VALUE", SetKeyValue);
    ScriptEngine::RegisterNativeHandler("GET_KEY_VALUE", GetKeyValue);
})

} // namespace counterstrikesharp

как можно убрать копирования свитч?