/*
 *
 *    Copyright (c) 2020-2021 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/util/attribute-storage-null-handling.h>
#include <lib/core/Optional.h>

#include <type_traits>

namespace chip {
namespace app {
namespace DataModel {

/**
 * NullNullable is an alias for NullOptional, for better readability.
 */
inline constexpr auto NullNullable = NullOptional;

/*
 * Dedicated type for nullable things, to differentiate them from optional
 * things.
 */
template <typename T>
struct Nullable : protected Optional<T>
{
    //
    // The following 'using' statement is needed to make visible
    // all constructors of the base class within this derived class.
    //
    using Optional<T>::Optional;

    // Pull in APIs that make sense on Nullable with the same names as on
    // Optional.
    using Optional<T>::Value;
    using Optional<T>::ValueOr;

    // Some consumers need an easy way to determine our underlying type.
    using UnderlyingType = T;

    constexpr void SetNull() { Optional<T>::ClearValue(); }
    constexpr bool IsNull() const { return !Optional<T>::HasValue(); }

    template <class... Args>
    constexpr T & SetNonNull(Args &&... args)
    {
        return Optional<T>::Emplace(std::forward<Args>(args)...);
    }

    // For integer types, being nullable involves a range restriction.
    template <
        typename U = std::decay_t<T>,
        typename std::enable_if_t<(std::is_integral<U>::value && !std::is_same<U, bool>::value) || std::is_enum<U>::value, int> = 0>
    constexpr bool ExistingValueInEncodableRange() const
    {
        return NumericAttributeTraits<T>::CanRepresentValue(/* isNullable = */ true, Value());
    }

    // For all other types, all values are valid.
    template <typename U                     = std::decay_t<T>,
              typename std::enable_if_t<(!std::is_integral<U>::value || std::is_same<U, bool>::value) && !std::is_enum<U>::value,
                                        int> = 0>
    constexpr bool ExistingValueInEncodableRange() const
    {
        return true;
    }

    // Set the nullable to the `other` nullable, returning true if something actually changed.
    // This can be used to determine if changes occurred on assignment, so that reporting can be triggered
    // only on actual changes.
    constexpr bool Update(const Nullable<T> & other)
    {
        bool changed = *this != other;
        if (changed)
        {
            *this = other;
        }
        return changed;
    }

    // The only fabric-scoped objects in the spec are commands, events and structs inside lists, and none of those can be nullable.
    static constexpr bool kIsFabricScoped = false;

    bool operator==(const Nullable & other) const { return Optional<T>::operator==(other); }
    bool operator!=(const Nullable & other) const { return Optional<T>::operator!=(other); }
    bool operator==(const T & other) const { return Optional<T>::operator==(other); }
    bool operator!=(const T & other) const { return Optional<T>::operator!=(other); }
};

template <class T>
constexpr Nullable<std::decay_t<T>> MakeNullable(T && value)
{
    return Nullable<std::decay_t<T>>(InPlace, std::forward<T>(value));
}

template <class T, class... Args>
constexpr Nullable<T> MakeNullable(Args &&... args)
{
    return Nullable<T>(InPlace, std::forward<Args>(args)...);
}

} // namespace DataModel
} // namespace app
} // namespace chip
