/*
 *   Copyright (c) 2024 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 <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 <string>
#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,
    Address,
    Complex,
    Custom,
    VectorBool,
    Vector16,
    Vector32,
    VectorCustom,
    VectorString, // comma separated string items
};

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; }
};

struct ReadOnlyGlobalCommandArgument
{
    const char * name;
    const char * value;
    const char * desc;
};

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 * GetReadOnlyGlobalCommandArgument(void) const;
    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);
    void AddArgument(const char * name, const char * value, const char * desc = "");
    /**
     * @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);
    // Optional Complex arguments are not currently supported via the <chip::Optional> class.
    // Instead, they must be explicitly specified as optional using kOptional in the flags parameter,
    // and the base TypedComplexArgument<T> class is referenced.
    size_t AddArgument(const char * name, ComplexArgument * value, const char * desc = "", uint8_t flags = 0);
    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);
    }

    size_t AddArgument(const char * name, std::vector<std::string> * value, const char * desc);
    size_t AddArgument(const char * name, chip::Optional<std::vector<std::string>> * value, const char * desc);

    void ResetArguments();

    virtual CHIP_ERROR Run() = 0;

    bool IsInteractive() { return mIsInteractive; }

    CHIP_ERROR RunAsInteractive(const chip::Optional<char *> & interactiveStorageDirectory, bool advertiseOperational)
    {
        mStorageDirectory     = interactiveStorageDirectory;
        mIsInteractive        = true;
        mAdvertiseOperational = advertiseOperational;
        return Run();
    }

    const chip::Optional<char *> & GetStorageDirectory() const { return mStorageDirectory; }

protected:
    // mStorageDirectory lives here so we can just set it in RunAsInteractive.
    chip::Optional<char *> mStorageDirectory;

    // mAdvertiseOperational lives here so we can just set it in
    // RunAsInteractive; it's only used by CHIPCommand.
    bool mAdvertiseOperational = false;

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;

    chip::Optional<ReadOnlyGlobalCommandArgument> mReadOnlyGlobalCommandArgument;
    std::vector<Argument> mArgs;
};
