/*
 *   Copyright (c) 2022 Project CHIP Authors
 *   All rights reserved.
 *
 *   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.
 *
 */

/**
 * This file allocate/free memory using the chip platform abstractions
 * (Platform::MemoryCalloc and Platform::MemoryFree) for hosting a subset of the
 * data model internal types until they are consumed by the DataModel::Encode machinery:
 *   - chip::app:DataModel::List<T>
 *   - chip::ByteSpan
 *   - chip::CharSpan
 *
 * Memory allocation happens during the 'Setup' phase, while memory deallocation happens
 * during the 'Finalize' phase.
 *
 * The 'Finalize' phase during the destructor phase, and if needed, 'Finalize' will call
 * the 'Finalize' phase of its descendant.
 */

#pragma once

#include <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/List.h>
#include <app/data-model/Nullable.h>
#include <commands/common/HexConversion.h>
#include <json/json.h>
#include <lib/core/Optional.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/SafeInt.h>

#include "JsonParser.h"

constexpr uint8_t kMaxLabelLength  = UINT8_MAX;
constexpr const char kNullString[] = "null";

class ComplexArgumentParser
{
public:
    ComplexArgumentParser() {}

    template <typename T,
              typename std::enable_if_t<std::is_integral<T>::value && !std::is_signed<T>::value &&
                                            !std::is_same<std::remove_cv_t<std::remove_reference_t<T>>, bool>::value,
                                        int> = 0>
    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
    {
        if (value.isNumeric())
        {
            if (chip::CanCastTo<T>(value.asLargestUInt()))
            {
                request = static_cast<T>(value.asLargestUInt());
                return CHIP_NO_ERROR;
            }
        }
        else if (value.isString())
        {
            // Check for a hex number; JSON does not support those as numbers,
            // so they have to be done as strings.  And we might as well support
            // string-encoded unsigned numbers in general if we're doing that.
            bool isHexNotation = strncmp(value.asCString(), "0x", 2) == 0 || strncmp(value.asCString(), "0X", 2) == 0;

            std::stringstream str;
            isHexNotation ? str << std::hex << value.asCString() : str << value.asCString();
            uint64_t val;
            str >> val;
            if (!str.fail() && str.eof() && chip::CanCastTo<T>(val))
            {
                request = static_cast<T>(val);
                return CHIP_NO_ERROR;
            }
        }

        ChipLogError(chipTool, "Error while encoding %s as an unsigned integer.", label);
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
    {
        if (!value.isNumeric() || !chip::CanCastTo<T>(value.asLargestInt()))
        {
            ChipLogError(chipTool, "Error while encoding %s as an unsigned integer.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        request = static_cast<T>(value.asLargestInt());
        return CHIP_NO_ERROR;
    }

    template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
    {
        std::underlying_type_t<T> requestValue;
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));

        request = static_cast<T>(requestValue);
        return CHIP_NO_ERROR;
    }

    template <typename T>
    static CHIP_ERROR Setup(const char * label, chip::BitFlags<T> & request, Json::Value & value)
    {
        T requestValue;
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));

        request = chip::BitFlags<T>(requestValue);
        return CHIP_NO_ERROR;
    }

    template <typename T>
    static CHIP_ERROR Setup(const char * label, chip::BitMask<T> & request, Json::Value & value)
    {
        T requestValue;
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));

        request = chip::BitMask<T>(requestValue);
        return CHIP_NO_ERROR;
    }

    template <typename T>
    static CHIP_ERROR Setup(const char * label, chip::Optional<T> & request, Json::Value & value)
    {
        T requestValue;
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));

        request = chip::Optional<T>(requestValue);
        return CHIP_NO_ERROR;
    }

    template <typename T>
    static CHIP_ERROR Setup(const char * label, chip::app::DataModel::Nullable<T> & request, Json::Value & value)
    {
        if (value.isNull())
        {
            request.SetNull();
            return CHIP_NO_ERROR;
        }

        T requestValue;
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));

        request = chip::app::DataModel::Nullable<T>(requestValue);
        return CHIP_NO_ERROR;
    }

    template <typename T>
    static CHIP_ERROR Setup(const char * label, chip::app::DataModel::List<T> & request, Json::Value & value)
    {
        if (!value.isArray())
        {
            ChipLogError(chipTool, "Error while encoding %s as an array.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        auto content = static_cast<typename std::remove_const<T>::type *>(chip::Platform::MemoryCalloc(value.size(), sizeof(T)));
        VerifyOrReturnError(content != nullptr, CHIP_ERROR_NO_MEMORY);

        Json::ArrayIndex size = value.size();
        for (Json::ArrayIndex i = 0; i < size; i++)
        {
            char labelWithIndex[kMaxLabelLength];
            // GCC 7.0.1 has introduced some new warnings for snprintf (-Werror=format-truncation) by default.
            // This is not particularly useful when using snprintf and especially in this context, so in order
            // to disable the warning the %s is constrained to be of max length: (254 - 11 - 2) where:
            //  - 254 is kMaxLabelLength - 1 (for null)
            //  - 11 is the maximum length of a %d (-2147483648, 2147483647)
            //  - 2 is the length for the "[" and "]" characters.
            snprintf(labelWithIndex, sizeof(labelWithIndex), "%.241s[%d]", label, i);
            ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithIndex, content[i], value[i]));
        }

        request = chip::app::DataModel::List<T>(content, value.size());
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR Setup(const char * label, chip::ByteSpan & request, Json::Value & value)
    {
        if (!value.isString())
        {
            ChipLogError(chipTool, "Error while encoding %s as an octet string: Not a string.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        auto str         = value.asString();
        auto size        = str.size();
        uint8_t * buffer = nullptr;

        if (IsStrString(str.c_str()))
        {
            // Skip the prefix
            str.erase(0, kStrStringPrefixLen);
            size = str.size();

            buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(size, sizeof(uint8_t)));
            VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_NO_MEMORY);

            memcpy(buffer, str.c_str(), size);
        }
        else
        {
            if (IsHexString(str.c_str()))
            {
                // Skip the prefix
                str.erase(0, kHexStringPrefixLen);
                size = str.size();
            }

            CHIP_ERROR err = HexToBytes(
                chip::CharSpan(str.c_str(), size),
                [&buffer](size_t allocSize) {
                    buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(allocSize, sizeof(uint8_t)));
                    return buffer;
                },
                &size);

            if (err != CHIP_NO_ERROR)
            {
                if (buffer != nullptr)
                {
                    chip::Platform::MemoryFree(buffer);
                }

                return err;
            }
        }

        request = chip::ByteSpan(buffer, size);
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR Setup(const char * label, chip::CharSpan & request, Json::Value & value)
    {
        if (!value.isString())
        {
            ChipLogError(chipTool, "Error while encoding %s as a string: Not a string.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        size_t size = strlen(value.asCString());
        auto buffer = static_cast<char *>(chip::Platform::MemoryCalloc(size, sizeof(char)));
        VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_NO_MEMORY);

        memcpy(buffer, value.asCString(), size);

        request = chip::CharSpan(buffer, size);
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR Setup(const char * label, float & request, Json::Value & value)
    {
        if (!value.isNumeric())
        {
            ChipLogError(chipTool, "Error while encoding %s as a float: Not a number.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        request = static_cast<float>(value.asFloat());
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR Setup(const char * label, double & request, Json::Value & value)
    {
        if (!value.isNumeric())
        {
            ChipLogError(chipTool, "Error while encoding %s as a double: Not a number.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        request = static_cast<double>(value.asDouble());
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR Setup(const char * label, bool & request, Json::Value & value)
    {
        if (!value.isBool())
        {
            ChipLogError(chipTool, "Error while encoding %s as a boolean: Not a boolean.", label);
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        request = value.asBool();
        return CHIP_NO_ERROR;
    }

    static CHIP_ERROR EnsureMemberExist(const char * label, const char * memberName, bool hasMember)
    {
        if (hasMember)
        {
            return CHIP_NO_ERROR;
        }

        ChipLogError(chipTool, "%s is required.  Should be provided as {\"%s\": value}", label, memberName);
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    static CHIP_ERROR EnsureNoMembersRemaining(const char * label, const Json::Value & value)
    {
        auto remainingFields = value.getMemberNames();
        if (remainingFields.size() == 0)
        {
            return CHIP_NO_ERROR;
        }
#if CHIP_ERROR_LOGGING
        for (auto & field : remainingFields)
        {
            ChipLogError(chipTool, "Unexpected field name: '%s.%s'", label, field.c_str());
        }
#endif // CHIP_ERROR_LOGGING
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    template <typename T>
    static void Finalize(T & request)
    {
        // Nothing to do
    }

    template <typename T>
    static void Finalize(chip::Optional<T> & request)
    {
        VerifyOrReturn(request.HasValue());
        ComplexArgumentParser::Finalize(request.Value());
    }

    template <typename T>
    static void Finalize(chip::app::DataModel::Nullable<T> & request)
    {
        VerifyOrReturn(!request.IsNull());
        ComplexArgumentParser::Finalize(request.Value());
    }

    static void Finalize(chip::ByteSpan & request)
    {
        VerifyOrReturn(request.data() != nullptr);
        chip::Platform::MemoryFree(reinterpret_cast<void *>(const_cast<uint8_t *>(request.data())));
    }

    static void Finalize(chip::CharSpan & request)
    {
        VerifyOrReturn(request.data() != nullptr);
        chip::Platform::MemoryFree(reinterpret_cast<void *>(const_cast<char *>(request.data())));
    }

    template <typename T>
    static void Finalize(chip::app::DataModel::List<T> & request)
    {
        VerifyOrReturn(request.data() != nullptr);

        size_t size = request.size();
        auto data   = const_cast<typename std::remove_const<T>::type *>(request.data());
        for (size_t i = 0; i < size; i++)
        {
            Finalize(data[i]);
        }

        chip::Platform::MemoryFree(reinterpret_cast<void *>(data));
    }

#include <zap-generated/cluster/ComplexArgumentParser.h>
};

class ComplexArgument
{
public:
    virtual ~ComplexArgument() {}

    virtual CHIP_ERROR Parse(const char * label, const char * json) = 0;

    virtual void Reset() = 0;
};

template <typename T>
class TypedComplexArgument : public ComplexArgument
{
public:
    TypedComplexArgument() {}
    TypedComplexArgument(T * request) : mRequest(request) {}
    ~TypedComplexArgument()
    {
        if (mRequest != nullptr)
        {
            ComplexArgumentParser::Finalize(*mRequest);
        }
    }

    void SetArgument(T * request) { mRequest = request; };

    CHIP_ERROR Parse(const char * label, const char * json)
    {
        Json::Value value;
        if (strcmp(kNullString, json) == 0)
        {
            value = Json::nullValue;
        }
        else if (!JsonParser::ParseComplexArgument(label, json, value))
        {
            return CHIP_ERROR_INVALID_ARGUMENT;
        }

        return ComplexArgumentParser::Setup(label, *mRequest, value);
    }

    void Reset() { *mRequest = T(); }

private:
    T * mRequest;
};
