#pragma once

#include <util/memory/blob.h>

#include <library/cpp/archive/yarchive.h>
#include <library/cpp/json/json_reader.h>

namespace NWebmaster {
namespace NUtils {

template <class T>
void ReadJsonFromArchive(const T &data, NJson::TJsonValue &json, int index = 0) {
    TArchiveReader archive(TBlob::NoCopy(data, Y_ARRAY_SIZE(data)));
    const TString key = archive.KeyByIndex(index);
    const TBlob blob = archive.ObjectBlobByKey(key);
    TMemoryInput in(blob.Data(), blob.Length());
    NJson::ReadJsonTree(&in, &json, true);
}

bool FromJsonNode(const NJson::TJsonValue &jsonNode, bool &value) {
    if (!jsonNode.IsNull()) {
        if (jsonNode.IsBoolean()) {
            value = jsonNode.GetBoolean();
            return true;
        } else if (jsonNode.IsInteger()) {
            value = jsonNode.GetInteger();
            return true;
        }
    }
    return false;
}

bool FromJsonNode(const NJson::TJsonValue &jsonNode, int &value) {
    if (!jsonNode.IsNull()) {
        value = jsonNode.GetInteger();
        return true;
    }
    return false;
}

bool FromJsonNode(const NJson::TJsonValue &jsonNode, TString &value) {
    if (!jsonNode.IsNull()) {
        value = jsonNode.GetString();
        return true;
    }
    return false;
}

template<class T>
bool FromJsonNode(const NJson::TJsonValue &jsonNode, TMaybe<T> &value) {
    T data;
    if (FromJsonNode(jsonNode, data)) {
        value = data;
        return true;
    }
    return false;
}

} //namespace NUtils
} //namespace NWebmaster
