//
// Copyright © 2019 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include "BackendId.hpp"
#include <armnn/Exceptions.hpp>
#include <cassert>

namespace armnn
{

struct BackendOptions;
using NetworkOptions = std::vector<BackendOptions>;

using ModelOptions = std::vector<BackendOptions>;
using BackendCapabilities = BackendOptions;

/// Struct for the users to pass backend specific options
struct BackendOptions
{
private:
    template<typename T>
    struct CheckAllowed
    {
        static const bool value = std::is_same<T, int>::value ||
                                  std::is_same<T, unsigned int>::value ||
                                  std::is_same<T, float>::value ||
                                  std::is_same<T, bool>::value ||
                                  std::is_same<T, std::string>::value ||
                                  std::is_same<T, const char*>::value;
    };
public:

    /// Very basic type safe variant
    class Var
    {

    public:
        /// Constructors
        explicit Var(int i) : m_Vals(i), m_Type(VarTypes::Integer) {};
        explicit Var(unsigned int u) : m_Vals(u), m_Type(VarTypes::UnsignedInteger) {};
        explicit Var(float f) : m_Vals(f), m_Type(VarTypes::Float) {};
        explicit Var(bool b) : m_Vals(b), m_Type(VarTypes::Boolean) {};
        explicit Var(const char* s) : m_Vals(s), m_Type(VarTypes::String) {};
        explicit Var(std::string s) : m_Vals(s), m_Type(VarTypes::String) {};

        /// Disallow implicit conversions from types not explicitly allowed below.
        template<typename DisallowedType>
        Var(DisallowedType)
        {
            static_assert(CheckAllowed<DisallowedType>::value, "Type is not allowed for Var<DisallowedType>.");
            assert(false && "Unreachable code");
        }

        /// Copy Construct
        Var(const Var& other)
            : m_Type(other.m_Type)
        {
            switch(m_Type)
            {
                case VarTypes::String:
                {
                    new (&m_Vals.s) std::string(other.m_Vals.s);
                    break;
                }
                default:
                {
                    DoOp(other, [](auto& a, auto& b)
                        {
                            a = b;
                        });
                    break;
                }
            }
        }

        /// Copy operator
        Var& operator=(const Var& other)
        {
            // Destroy existing string
            if (m_Type == VarTypes::String)
            {
                Destruct(m_Vals.s);
            }

            m_Type = other.m_Type;
            switch(m_Type)
            {
                case VarTypes::String:
                {

                    new (&m_Vals.s) std::string(other.m_Vals.s);
                    break;
                }
                default:
                {
                    DoOp(other, [](auto& a, auto& b)
                        {
                            a = b;
                        });
                    break;
                }
            }

            return *this;
        };

        /// Type getters
        bool IsBool() const { return m_Type == VarTypes::Boolean; }
        bool IsInt() const { return m_Type == VarTypes::Integer; }
        bool IsUnsignedInt() const { return m_Type == VarTypes::UnsignedInteger; }
        bool IsFloat() const { return m_Type == VarTypes::Float; }
        bool IsString() const { return m_Type == VarTypes::String; }

        /// Value getters
        bool AsBool() const { assert(IsBool()); return m_Vals.b; }
        int AsInt() const { assert(IsInt()); return m_Vals.i; }
        unsigned int AsUnsignedInt() const { assert(IsUnsignedInt()); return m_Vals.u; }
        float AsFloat() const { assert(IsFloat()); return m_Vals.f; }
        std::string AsString() const { assert(IsString()); return m_Vals.s; }
        std::string ToString()
        {
            if (IsBool()) { return AsBool() ? "true" : "false"; }
            else if (IsInt()) { return std::to_string(AsInt()); }
            else if (IsUnsignedInt()) { return std::to_string(AsUnsignedInt()); }
            else if (IsFloat()) { return std::to_string(AsFloat()); }
            else if (IsString()) { return AsString(); }
            else
            {
                throw armnn::InvalidArgumentException("Unknown data type for string conversion");
            }
        }

        /// Destructor
        ~Var()
        {
            DoOp(*this, [this](auto& a, auto&)
                {
                    Destruct(a);
                });
        }
    private:
        template<typename Func>
        void DoOp(const Var& other, Func func)
        {
            if (other.IsBool())
            {
                func(m_Vals.b, other.m_Vals.b);
            }
            else if (other.IsInt())
            {
                func(m_Vals.i, other.m_Vals.i);
            }
            else if (other.IsUnsignedInt())
            {
                func(m_Vals.u, other.m_Vals.u);
            }
            else if (other.IsFloat())
            {
                func(m_Vals.f, other.m_Vals.f);
            }
            else if (other.IsString())
            {
                func(m_Vals.s, other.m_Vals.s);
            }
        }

        template<typename Destructable>
        void Destruct(Destructable& d)
        {
            if (std::is_destructible<Destructable>::value)
            {
                d.~Destructable();
            }
        }

    private:
        /// Types which can be stored
        enum class VarTypes
        {
            Boolean,
            Integer,
            Float,
            String,
            UnsignedInteger
        };

        /// Union of potential type values.
        union Vals
        {
            int i;
            unsigned int u;
            float f;
            bool b;
            std::string s;

            Vals(){}
            ~Vals(){}

            explicit Vals(int i) : i(i) {};
            explicit Vals(unsigned int u) : u(u) {};
            explicit Vals(float f) : f(f) {};
            explicit Vals(bool b) : b(b) {};
            explicit Vals(const char* s) : s(std::string(s)) {}
            explicit Vals(std::string s) : s(s) {}
       };

        Vals m_Vals;
        VarTypes m_Type;
    };

    struct BackendOption
    {
    public:
        BackendOption(std::string name, bool value)
            : m_Name(name), m_Value(value)
        {}
        BackendOption(std::string name, int value)
            : m_Name(name), m_Value(value)
        {}
        BackendOption(std::string name, unsigned int value)
                : m_Name(name), m_Value(value)
        {}
        BackendOption(std::string name, float value)
            : m_Name(name), m_Value(value)
        {}
        BackendOption(std::string name, std::string value)
            : m_Name(name), m_Value(value)
        {}
        BackendOption(std::string name, const char* value)
            : m_Name(name), m_Value(value)
        {}

        template<typename DisallowedType>
        BackendOption(std::string, DisallowedType)
            : m_Value(0)
        {
            static_assert(CheckAllowed<DisallowedType>::value, "Type is not allowed for BackendOption.");
            assert(false && "Unreachable code");
        }

        BackendOption(const BackendOption& other) = default;
        BackendOption(BackendOption&& other) = default;
        BackendOption& operator=(const BackendOption& other) = default;
        BackendOption& operator=(BackendOption&& other) = default;
        ~BackendOption() = default;

        std::string GetName() const   { return m_Name; }
        Var GetValue() const          { return m_Value; }

    private:
        std::string m_Name;         ///< Name of the option
        Var         m_Value;        ///< Value of the option. (Bool, int, Float, String)
    };

    explicit BackendOptions(BackendId backend)
        : m_TargetBackend(backend)
    {}

    BackendOptions(BackendId backend, std::initializer_list<BackendOption> options)
        : m_TargetBackend(backend)
        , m_Options(options)
    {}

    BackendOptions(const BackendOptions& other) = default;
    BackendOptions(BackendOptions&& other) = default;
    BackendOptions& operator=(const BackendOptions& other) = default;
    BackendOptions& operator=(BackendOptions&& other) = default;

    void AddOption(BackendOption&& option)
    {
        m_Options.push_back(option);
    }

    void AddOption(const BackendOption& option)
    {
        m_Options.push_back(option);
    }

    const BackendId& GetBackendId() const noexcept { return m_TargetBackend; }
    size_t GetOptionCount() const noexcept { return m_Options.size(); }
    const BackendOption& GetOption(size_t idx) const { return m_Options[idx]; }

private:
    /// The id for the backend to which the options should be passed.
    BackendId m_TargetBackend;

    /// The array of options to pass to the backend context
    std::vector<BackendOption> m_Options;
};


template <typename F>
void ParseOptions(const std::vector<BackendOptions>& options, BackendId backend, F f)
{
    for (auto optionsGroup : options)
    {
        if (optionsGroup.GetBackendId() == backend)
        {
            for (size_t i=0; i < optionsGroup.GetOptionCount(); i++)
            {
                const BackendOptions::BackendOption option = optionsGroup.GetOption(i);
                f(option.GetName(), option.GetValue());
            }
        }
    }
}

inline bool ParseBooleanBackendOption(const armnn::BackendOptions::Var& value, bool defaultValue)
{
    if (value.IsBool())
    {
        return value.AsBool();
    }
    return defaultValue;
}

inline std::string ParseStringBackendOption(const armnn::BackendOptions::Var& value, std::string defaultValue)
{
    if (value.IsString())
    {
        return value.AsString();
    }
    return defaultValue;
}

inline int ParseIntBackendOption(const armnn::BackendOptions::Var& value, int defaultValue)
{
    if (value.IsInt())
    {
        return value.AsInt();
    }
    return defaultValue;
}

} //namespace armnn
