#pragma once
#include "./basic_types.hpp"

namespace lsp::protocol
{

    inline LSPAny::LSPAny() :
        value(nullptr) {}

    inline LSPAny::LSPAny(const LSPAny& other) :
        value(other.value) {}

    inline LSPAny::LSPAny(LSPAny&& other) noexcept :
        value(std::move(other.value)) {}

    inline LSPAny::LSPAny(const std::map<string, LSPAny>& val) :
        value(val) {}

    inline LSPAny::LSPAny(std::map<string, LSPAny>&& val) :
        value(std::move(val)) {}

    inline LSPAny::LSPAny(const std::vector<LSPAny>& val) :
        value(val) {}

    inline LSPAny::LSPAny(std::vector<LSPAny>&& val) :
        value(std::move(val)) {}

    inline LSPAny::LSPAny(const string& val) :
        value(val) {}

    inline LSPAny::LSPAny(string&& val) :
        value(std::move(val)) {}

    inline LSPAny::LSPAny(const char* val) :
        value(string(val)) {}

    inline LSPAny::LSPAny(int val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(long val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(long long val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(unsigned int val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(unsigned long val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(unsigned long long val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(float val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(double val) :
        value(val) {}

    inline LSPAny::LSPAny(long double val) :
        value(static_cast<decimal>(val)) {}

    inline LSPAny::LSPAny(boolean val) :
        value(val) {}

    inline LSPAny::LSPAny(std::nullptr_t) :
        value(nullptr) {}

    // 赋值操作符
    inline LSPAny& LSPAny::operator=(const LSPAny& other)
    {
        value = other.value;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(LSPAny&& other) noexcept
    {
        value = std::move(other.value);
        return *this;
    }

    // 针对每种支持的类型的赋值操作符
    inline LSPAny& LSPAny::operator=(const std::map<string, LSPAny>& val)
    {
        value = val;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(std::map<string, LSPAny>&& val)
    {
        value = std::move(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(const std::vector<LSPAny>& val)
    {
        value = val;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(std::vector<LSPAny>&& val)
    {
        value = std::move(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(const string& val)
    {
        value = val;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(string&& val)
    {
        value = std::move(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(const char* val)
    {
        value = string(val);
        return *this;
    }

    // 所有数字类型都转换为 decimal
    inline LSPAny& LSPAny::operator=(int val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(long val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(long long val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(unsigned int val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(unsigned long val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(unsigned long long val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(float val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(double val)
    {
        value = val;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(long double val)
    {
        value = static_cast<decimal>(val);
        return *this;
    }

    inline LSPAny& LSPAny::operator=(boolean val)
    {
        value = val;
        return *this;
    }

    inline LSPAny& LSPAny::operator=(std::nullptr_t)
    {
        value = nullptr;
        return *this;
    }

}
