// Copyright (c) 2023, ARM Limited.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//         http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

#include "generate_utils.h"

#include <nlohmann/json.hpp>

#include <algorithm>

namespace tosa
{

NLOHMANN_JSON_SERIALIZE_ENUM(DType,
                             {
                                 { DType::DType_UNKNOWN, "UNKNOWN" },
                                 { DType::DType_BOOL, "BOOL" },
                                 { DType::DType_INT4, "INT4" },
                                 { DType::DType_INT8, "INT8" },
                                 { DType::DType_INT16, "INT16" },
                                 { DType::DType_INT32, "INT32" },
                                 { DType::DType_INT48, "INT48" },
                                 { DType::DType_FP16, "FP16" },
                                 { DType::DType_BF16, "BF16" },
                                 { DType::DType_FP32, "FP32" },
                             })

NLOHMANN_JSON_SERIALIZE_ENUM(Op,
                             {
                                 { Op::Op_UNKNOWN, "UNKNOWN" },
                                 { Op::Op_ABS, "ABS" },
                                 { Op::Op_ADD, "ADD" },
                                 { Op::Op_ARGMAX, "ARGMAX" },
                                 { Op::Op_AVG_POOL2D, "AVG_POOL2D" },
                                 { Op::Op_CEIL, "CEIL" },
                                 { Op::Op_CLAMP, "CLAMP" },
                                 { Op::Op_CONV2D, "CONV2D" },
                                 { Op::Op_ERF, "ERF" },
                                 { Op::Op_EXP, "EXP" },
                                 { Op::Op_FLOOR, "FLOOR" },
                                 { Op::Op_FULLY_CONNECTED, "FULLY_CONNECTED" },
                                 { Op::Op_IDENTITY, "IDENTITY" },
                                 { Op::Op_LOG, "LOG" },
                                 { Op::Op_MATMUL, "MATMUL" },
                                 { Op::Op_MAXIMUM, "MAXIMUM" },
                                 { Op::Op_MAX_POOL2D, "MAX_POOL2D" },
                                 { Op::Op_MINIMUM, "MINIMUM" },
                                 { Op::Op_MUL, "MUL" },
                                 { Op::Op_NEGATE, "NEGATE" },
                                 { Op::Op_PAD, "PAD" },
                                 { Op::Op_POW, "POW" },
                                 { Op::Op_RECIPROCAL, "RECIPROCAL" },
                                 { Op::Op_RSQRT, "RSQRT" },
                                 { Op::Op_REDUCE_MAX, "REDUCE_MAX" },
                                 { Op::Op_REDUCE_MIN, "REDUCE_MIN" },
                                 { Op::Op_REDUCE_SUM, "REDUCE_SUM" },
                                 { Op::Op_SIGMOID, "SIGMOID" },
                                 { Op::Op_SUB, "SUB" },
                                 { Op::Op_TANH, "TANH" },
                             })

}    // namespace tosa

namespace TosaReference
{

NLOHMANN_JSON_SERIALIZE_ENUM(GeneratorType,
                             {
                                 { GeneratorType::Unknown, "UNKNOWN" },
                                 { GeneratorType::PseudoRandom, "PSEUDO_RANDOM" },
                                 { GeneratorType::DotProduct, "DOT_PRODUCT" },
                                 { GeneratorType::OpFullRange, "OP_FULL_RANGE" },
                                 { GeneratorType::OpBoundary, "OP_BOUNDARY" },
                                 { GeneratorType::OpSpecial, "OP_SPECIAL" },
                             })

// NOTE: This assumes it's VARIABLE if the InputType is not recognized
NLOHMANN_JSON_SERIALIZE_ENUM(InputType,
                             {
                                 { InputType::Variable, "VARIABLE" },
                                 { InputType::Constant, "CONSTANT" },
                             })

void from_json(const nlohmann::json& j, DotProductInfo& dotProductInfo)
{
    j.at("s").get_to(dotProductInfo.s);
    j.at("ks").get_to(dotProductInfo.ks);
    j.at("acc_type").get_to(dotProductInfo.accType);
    if (j.contains("kernel"))
    {
        j.at("kernel").get_to(dotProductInfo.kernel);
    }
    if (j.contains("axis"))
    {
        j.at("axis").get_to(dotProductInfo.axis);
    }
}

void from_json(const nlohmann::json& j, PseudoRandomInfo& pseudoRandomInfo)
{
    j.at("rng_seed").get_to(pseudoRandomInfo.rngSeed);
    if (j.contains("range"))
    {
        j.at("range").get_to(pseudoRandomInfo.range);
    }
}

void from_json(const nlohmann::json& j, GenerateConfig& cfg)
{
    j.at("data_type").get_to(cfg.dataType);
    j.at("input_type").get_to(cfg.inputType);
    j.at("shape").get_to(cfg.shape);
    j.at("input_pos").get_to(cfg.inputPos);
    j.at("op").get_to(cfg.opType);
    j.at("generator").get_to(cfg.generatorType);
    if (j.contains("dot_product_info"))
    {
        j.at("dot_product_info").get_to(cfg.dotProductInfo);
    }
    if (j.contains("pseudo_random_info"))
    {
        j.at("pseudo_random_info").get_to(cfg.pseudoRandomInfo);
    }
}

std::optional<GenerateConfig> parseGenerateConfig(const char* json, const char* tensorName)
{
    if (!tensorName)
        return std::nullopt;

    auto jsonCfg = nlohmann::json::parse(json, nullptr, /* allow exceptions */ false);

    if (jsonCfg.is_discarded())
    {
        WARNING("[Generator] Invalid json config.");
        return std::nullopt;
    }
    if (!jsonCfg.contains("tensors"))
    {
        WARNING("[Generator] Missing tensors in json config.");
        return std::nullopt;
    }
    const auto& tensors = jsonCfg["tensors"];
    if (!tensors.contains(tensorName))
    {
        WARNING("[Generator] Missing tensor %s in json config.", tensorName);
        return std::nullopt;
    }
    const auto& namedTensor = tensors[tensorName];
    return namedTensor.get<GenerateConfig>();
}

int64_t numElementsFromShape(const std::vector<int32_t>& shape)
{
    // Rank 0 shapes have no entries and so this will return 1
    // Other ranked shapes will return the product of their dimensions
    return std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<int64_t>());
}

size_t elementSizeFromType(DType type)
{
    switch (type)
    {
        case DType::DType_BOOL:
        case DType::DType_UINT8:
        case DType::DType_INT8:
            return 1;
        case DType::DType_UINT16:
        case DType::DType_INT16:
        case DType::DType_FP16:
        case DType::DType_BF16:
            return 2;
        case DType::DType_INT32:
        case DType::DType_FP32:
            return 4;
        default:
            return 0;
    }
    return 0;
}
}    // namespace TosaReference
