/*
 *   Copyright (c) 2020 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.
 *
 */

#pragma once

#include <app/data-model/Nullable.h>
#include <commands/clusters/ComplexArgument.h>
#include <commands/clusters/CustomArgument.h>
#include <controller/CHIPDeviceController.h>
#include <inet/InetInterface.h>
#include <lib/core/Optional.h>
#include <lib/support/Span.h>
#include <lib/support/logging/CHIPLogging.h>

#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <vector>

class Command;

template <typename T, typename... Args>
std::unique_ptr<Command> make_unique(Args &&... args)
{
    return std::unique_ptr<Command>(new T(std::forward<Args>(args)...));
}

struct movable_initializer_list
{
    movable_initializer_list(std::unique_ptr<Command> && in) : item(std::move(in)) {}
    operator std::unique_ptr<Command>() const && { return std::move(item); }
    mutable std::unique_ptr<Command> item;
};

typedef std::initializer_list<movable_initializer_list> commands_list;

enum ArgumentType
{
    Number_uint8,
    Number_uint16,
    Number_uint32,
    Number_uint64,
    Number_int8,
    Number_int16,
    Number_int32,
    Number_int64,
    Float,
    Double,
    Bool,
    String,
    CharString,
    OctetString,
    Attribute,
    Address,
    Complex,
    Custom,
    VectorBool,
    Vector16,
    Vector32,
    VectorCustom,
};

struct Argument
{
    const char * name;
    ArgumentType type;
    int64_t min;
    uint64_t max;
    void * value;
    uint8_t flags;
    const char * desc;

    enum
    {
        kOptional = (1 << 0),
        kNullable = (1 << 1),
    };

    bool isOptional() const { return flags & kOptional; }
    bool isNullable() const { return flags & kNullable; }
};

class Command
{
public:
    struct AddressWithInterface
    {
        ::chip::Inet::IPAddress address;
        ::chip::Inet::InterfaceId interfaceId;
    };

    Command(const char * commandName, const char * helpText = nullptr) : mName(commandName), mHelpText(helpText) {}
    virtual ~Command() {}

    const char * GetName(void) const { return mName; }
    const char * GetHelpText() const { return mHelpText; }
    const char * GetAttribute(void) const;
    const char * GetEvent(void) const;
    const char * GetArgumentName(size_t index) const;
    const char * GetArgumentDescription(size_t index) const;
    bool GetArgumentIsOptional(size_t index) const { return mArgs[index].isOptional(); }
    size_t GetArgumentsCount(void) const { return mArgs.size(); }

    bool InitArguments(int argc, char ** argv);
    size_t AddArgument(const char * name, const char * value, const char * desc = "", uint8_t flags = 0);
    /**
     * @brief
     *   Add a char string command argument
     *
     * @param name  The name that will be displayed in the command help
     * @param value A pointer to a `char *` where the argv value will be stored
     * @param flags
     * @param desc The description of the argument that will be displayed in the command help
     * @returns The number of arguments currently added to the command
     */
    size_t AddArgument(const char * name, char ** value, const char * desc = "", uint8_t flags = 0);

    /**
     * Add an octet string command argument
     */
    size_t AddArgument(const char * name, chip::ByteSpan * value, const char * desc = "", uint8_t flags = 0);
    size_t AddArgument(const char * name, chip::Span<const char> * value, const char * desc = "", uint8_t flags = 0);
    size_t AddArgument(const char * name, AddressWithInterface * out, const char * desc = "", uint8_t flags = 0);
    size_t AddArgument(const char * name, ComplexArgument * value, const char * desc = "");
    size_t AddArgument(const char * name, CustomArgument * value, const char * desc = "");
    size_t AddArgument(const char * name, int64_t min, uint64_t max, bool * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Bool, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, int8_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int8, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, int16_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int16, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, int32_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int32, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, int64_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int64, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint8_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint8, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint16_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint16, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint32_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint32, desc, flags);
    }
    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint64_t * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint64, desc, flags);
    }

    size_t AddArgument(const char * name, float min, float max, float * out, const char * desc = "", uint8_t flags = 0);
    size_t AddArgument(const char * name, double min, double max, double * out, const char * desc = "", uint8_t flags = 0);

    size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint16_t> * value, const char * desc = "");
    size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint32_t> * value, const char * desc = "");
    size_t AddArgument(const char * name, std::vector<CustomArgument *> * value, const char * desc = "");
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<bool>> * value,
                       const char * desc = "");
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<uint32_t>> * value,
                       const char * desc = "");

    template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
    size_t AddArgument(const char * name, int64_t min, uint64_t max, T * out, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<std::underlying_type_t<T> *>(out), desc, flags);
    }

    template <typename T>
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitFlags<T> * out, const char * desc = "",
                       uint8_t flags = 0)
    {
        // This is a terrible hack that relies on BitFlags only having the one
        // mValue member.
        return AddArgument(name, min, max, reinterpret_cast<T *>(out), desc, flags);
    }

    template <typename T>
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitMask<T> * out, const char * desc = "",
                       uint8_t flags = 0)
    {
        // This is a terrible hack that relies on BitMask only having the one
        // mValue member.
        return AddArgument(name, min, max, reinterpret_cast<T *>(out), desc, flags);
    }

    template <typename T>
    size_t AddArgument(const char * name, chip::Optional<T> * value, const char * desc = "")
    {
        return AddArgument(name, reinterpret_cast<T *>(value), desc, Argument::kOptional);
    }

    template <typename T>
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<T> * value, const char * desc = "")
    {
        return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, Argument::kOptional);
    }

    template <typename T>
    size_t AddArgument(const char * name, chip::app::DataModel::Nullable<T> * value, const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
    }

    template <typename T>
    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::app::DataModel::Nullable<T> * value,
                       const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
    }

    size_t AddArgument(const char * name, float min, float max, chip::app::DataModel::Nullable<float> * value,
                       const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<float *>(value), desc, flags | Argument::kNullable);
    }

    size_t AddArgument(const char * name, double min, double max, chip::app::DataModel::Nullable<double> * value,
                       const char * desc = "", uint8_t flags = 0)
    {
        return AddArgument(name, min, max, reinterpret_cast<double *>(value), desc, flags | Argument::kNullable);
    }

    void ResetArguments();

    virtual CHIP_ERROR Run() = 0;

    bool IsInteractive() { return mIsInteractive; }

    CHIP_ERROR RunAsInteractive()
    {
        mIsInteractive = true;
        return Run();
    }

private:
    bool InitArgument(size_t argIndex, char * argValue);
    size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, const char * desc,
                       uint8_t flags);
    size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, const char * desc, uint8_t flags);

    /**
     * Add the Argument to our list.  This preserves the property that all
     * optional arguments come at the end of the list.
     */
    size_t AddArgumentToList(Argument && argument);

    const char * mName     = nullptr;
    const char * mHelpText = nullptr;
    bool mIsInteractive    = false;
    std::vector<Argument> mArgs;
};
