/*
 *
 *    Copyright (c) 2021-2022 Project CHIP Authors
 *
 *    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 <optional>
#include <stdint.h>
#include <sys/types.h>

#include <app/util/basic-types.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/core/ClusterEnums.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/CommonIterator.h>

namespace chip {
namespace Credentials {

class GroupDataProvider
{
public:
    using SecurityPolicy                                  = app::Clusters::GroupKeyManagement::GroupKeySecurityPolicyEnum;
    static constexpr KeysetId kIdentityProtectionKeySetId = 0;

    struct GroupInfo
    {
        static constexpr size_t kGroupNameMax = CHIP_CONFIG_MAX_GROUP_NAME_LENGTH;

        // Identifies group within the scope of the given Fabric
        GroupId group_id = kUndefinedGroupId;
        // Lastest group name written for a given GroupId on any Endpoint via the Groups cluster
        char name[kGroupNameMax + 1] = { 0 };

        GroupInfo() { SetName(nullptr); }
        GroupInfo(const char * groupName) { SetName(groupName); }
        GroupInfo(const CharSpan & groupName) { SetName(groupName); }
        GroupInfo(GroupId id, const char * groupName) : group_id(id) { SetName(groupName); }
        GroupInfo(GroupId id, const CharSpan & groupName) : group_id(id) { SetName(groupName); }
        void SetName(const char * groupName)
        {
            if (nullptr == groupName)
            {
                name[0] = 0;
            }
            else
            {
                Platform::CopyString(name, groupName);
            }
        }
        void SetName(const CharSpan & groupName)
        {
            if (nullptr == groupName.data())
            {
                name[0] = 0;
            }
            else
            {
                Platform::CopyString(name, groupName);
            }
        }
        bool operator==(const GroupInfo & other) const
        {
            return (this->group_id == other.group_id) && !strncmp(this->name, other.name, kGroupNameMax);
        }
    };

    struct GroupKey
    {
        GroupKey() = default;
        GroupKey(GroupId group, KeysetId keyset) : group_id(group), keyset_id(keyset) {}
        // Identifies group within the scope of the given Fabric
        GroupId group_id = kUndefinedGroupId;
        // Set of group keys that generate operational group keys for use with this group
        KeysetId keyset_id = 0;
        bool operator==(const GroupKey & other) const
        {
            return this->group_id == other.group_id && this->keyset_id == other.keyset_id;
        }
    };

    struct GroupEndpoint
    {
        GroupEndpoint() = default;
        GroupEndpoint(GroupId group, EndpointId endpoint) : group_id(group), endpoint_id(endpoint) {}
        // Identifies group within the scope of the given Fabric
        GroupId group_id = kUndefinedGroupId;
        // Endpoint on the Node to which messages to this group may be forwarded
        EndpointId endpoint_id = kInvalidEndpointId;

        bool operator==(const GroupEndpoint & other) const
        {
            return this->group_id == other.group_id && this->endpoint_id == other.endpoint_id;
        }
    };

    struct GroupSession
    {
        GroupSession()   = default;
        GroupId group_id = kUndefinedGroupId;
        FabricIndex fabric_index;
        SecurityPolicy security_policy;
        Crypto::SymmetricKeyContext * keyContext = nullptr;
    };

    // An EpochKey is a single key usable to determine an operational group key
    struct EpochKey
    {
        static constexpr size_t kLengthBytes = Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES;
        // Validity start time in microseconds since 2000-01-01T00:00:00 UTC ("the Epoch")
        uint64_t start_time;
        // Actual key bits. Depending on context, it may be a raw epoch key (as seen within `SetKeySet` calls)
        // or it may be the derived operational group key (as seen in any other usage).
        uint8_t key[kLengthBytes];

        void Clear()
        {
            start_time = 0;
            Crypto::ClearSecretData(&key[0], sizeof(key));
        }
    };

    // A operational group key set, usable by many GroupState mappings
    struct KeySet
    {
        static constexpr size_t kEpochKeysMax = 3;

        KeySet() = default;
        KeySet(uint16_t id, SecurityPolicy policy_id, uint8_t num_keys) : keyset_id(id), policy(policy_id), num_keys_used(num_keys)
        {}

        // The actual keys for the group key set
        EpochKey epoch_keys[kEpochKeysMax];
        // Logical id provided by the Administrator that configured the entry
        uint16_t keyset_id = 0;
        // Security policy to use for groups that use this keyset
        SecurityPolicy policy = SecurityPolicy::kCacheAndSync;
        // Number of keys present
        uint8_t num_keys_used = 0;

        bool operator==(const KeySet & other) const
        {
            VerifyOrReturnError(this->policy == other.policy && this->num_keys_used == other.num_keys_used, false);
            return !memcmp(this->epoch_keys, other.epoch_keys, this->num_keys_used * sizeof(EpochKey));
        }

        void ClearKeys()
        {
            for (size_t key_idx = 0; key_idx < kEpochKeysMax; ++key_idx)
            {
                epoch_keys[key_idx].Clear();
            }
        }
    };

    /**
     *  Interface to listen for changes in the Group info.
     */
    class GroupListener
    {
    public:
        virtual ~GroupListener() = default;
        /**
         *  Callback invoked when a new group is added.
         *
         *  @param[in] new_group  GroupInfo structure of the new group.
         */
        virtual void OnGroupAdded(FabricIndex fabric_index, const GroupInfo & new_group) = 0;
        /**
         *  Callback invoked when an existing group is removed.
         *
         *  @param[in] old_group  GroupInfo structure of the removed group.
         */
        virtual void OnGroupRemoved(FabricIndex fabric_index, const GroupInfo & old_group) = 0;
    };

    using GroupInfoIterator    = CommonIterator<GroupInfo>;
    using GroupKeyIterator     = CommonIterator<GroupKey>;
    using EndpointIterator     = CommonIterator<GroupEndpoint>;
    using KeySetIterator       = CommonIterator<KeySet>;
    using GroupSessionIterator = CommonIterator<GroupSession>;

    GroupDataProvider(uint16_t maxGroupsPerFabric    = CHIP_CONFIG_MAX_GROUPS_PER_FABRIC,
                      uint16_t maxGroupKeysPerFabric = CHIP_CONFIG_MAX_GROUP_KEYS_PER_FABRIC) :
        mMaxGroupsPerFabric(maxGroupsPerFabric),
        mMaxGroupKeysPerFabric(maxGroupKeysPerFabric)
    {}

    virtual ~GroupDataProvider() = default;

    // Not copyable
    GroupDataProvider(const GroupDataProvider &)             = delete;
    GroupDataProvider & operator=(const GroupDataProvider &) = delete;

    uint16_t GetMaxGroupsPerFabric() const { return mMaxGroupsPerFabric; }
    uint16_t GetMaxGroupKeysPerFabric() const { return mMaxGroupKeysPerFabric; }

    /**
     *  Initialize the GroupDataProvider, including possibly any persistent
     *  data store initialization done by the implementation. Must be called once
     *  before any other API succeeds.
     *
     *  @retval #CHIP_ERROR_INCORRECT_STATE if called when already initialized.
     *  @retval #CHIP_NO_ERROR on success
     */
    virtual CHIP_ERROR Init() = 0;
    virtual void Finish()     = 0;

    //
    // Group Table
    //

    // By id
    virtual CHIP_ERROR SetGroupInfo(FabricIndex fabric_index, const GroupInfo & info)             = 0;
    virtual CHIP_ERROR GetGroupInfo(FabricIndex fabric_index, GroupId group_id, GroupInfo & info) = 0;
    virtual CHIP_ERROR RemoveGroupInfo(FabricIndex fabric_index, GroupId group_id)                = 0;
    // By index
    virtual CHIP_ERROR SetGroupInfoAt(FabricIndex fabric_index, size_t index, const GroupInfo & info) = 0;
    virtual CHIP_ERROR GetGroupInfoAt(FabricIndex fabric_index, size_t index, GroupInfo & info)       = 0;
    virtual CHIP_ERROR RemoveGroupInfoAt(FabricIndex fabric_index, size_t index)                      = 0;
    // Endpoints
    virtual bool HasEndpoint(FabricIndex fabric_index, GroupId group_id, EndpointId endpoint_id)          = 0;
    virtual CHIP_ERROR AddEndpoint(FabricIndex fabric_index, GroupId group_id, EndpointId endpoint_id)    = 0;
    virtual CHIP_ERROR RemoveEndpoint(FabricIndex fabric_index, GroupId group_id, EndpointId endpoint_id) = 0;
    virtual CHIP_ERROR RemoveEndpoint(FabricIndex fabric_index, EndpointId endpoint_id)                   = 0;
    // Iterators
    /**
     *  Creates an iterator that may be used to obtain the list of groups associated with the given fabric.
     *  In order to release the allocated memory, the Release() method must be called after the iteration is finished.
     *  Modifying the group table during the iteration is currently not supported, and may yield unexpected behaviour.
     *  @retval An instance of EndpointIterator on success
     *  @retval nullptr if no iterator instances are available.
     */
    virtual GroupInfoIterator * IterateGroupInfo(FabricIndex fabric_index) = 0;
    /**
     *  Creates an iterator that may be used to obtain the list of (group, endpoint) pairs associated with the given fabric.
     *  In order to release the allocated memory, the Release() method must be called after the iteration is finished.
     *  Modifying the group table during the iteration is currently not supported, and may yield unexpected behaviour.
     *  If you wish to iterate only the endpoints of a particular group id you can provide the optional `group_id` to do so.
     *  @retval An instance of EndpointIterator on success
     *  @retval nullptr if no iterator instances are available.
     */
    virtual EndpointIterator * IterateEndpoints(FabricIndex fabric_index, std::optional<GroupId> group_id = std::nullopt) = 0;

    //
    // Group-Key map
    //

    virtual CHIP_ERROR SetGroupKeyAt(FabricIndex fabric_index, size_t index, const GroupKey & info) = 0;
    virtual CHIP_ERROR GetGroupKeyAt(FabricIndex fabric_index, size_t index, GroupKey & info)       = 0;
    virtual CHIP_ERROR RemoveGroupKeyAt(FabricIndex fabric_index, size_t index)                     = 0;
    virtual CHIP_ERROR RemoveGroupKeys(FabricIndex fabric_index)                                    = 0;

    /**
     *  Creates an iterator that may be used to obtain the list of (group, keyset) pairs associated with the given fabric.
     *  In order to release the allocated memory, the Release() method must be called after the iteration is finished.
     *  Modifying the keyset mappings during the iteration is currently not supported, and may yield unexpected behaviour.
     *  @retval An instance of GroupKeyIterator on success
     *  @retval nullptr if no iterator instances are available.
     */
    virtual GroupKeyIterator * IterateGroupKeys(FabricIndex fabric_index) = 0;

    //
    // Key Sets
    //

    virtual CHIP_ERROR SetKeySet(FabricIndex fabric_index, const ByteSpan & compressed_fabric_id, const KeySet & keys) = 0;
    virtual CHIP_ERROR GetKeySet(FabricIndex fabric_index, KeysetId keyset_id, KeySet & keys)                          = 0;
    virtual CHIP_ERROR RemoveKeySet(FabricIndex fabric_index, KeysetId keyset_id)                                      = 0;

    /**
     * @brief Obtain the actual operational Identity Protection Key (IPK) keyset for a given
     *        fabric. These keys are used by the CASE protocol, and do not participate in
     *        any direct traffic encryption. Since the identity protection operational keyset
     *        is used in multiple key derivations and procedures, it cannot be hidden behind a
     *        SymmetricKeyContext, and must be obtainable by value.
     *
     * @param fabric_index - Fabric index for which to get the IPK operational keyset
     * @param out_keyset - Reference to a KeySet where the IPK keys will be stored on success
     * @return CHIP_NO_ERROR on success, CHIP_ERROR_NOT_FOUND if the IPK keyset is somehow unavailable
     *         or another CHIP_ERROR value if an internal storage error occurs.
     */
    virtual CHIP_ERROR GetIpkKeySet(FabricIndex fabric_index, KeySet & out_keyset) = 0;

    /**
     *  Creates an iterator that may be used to obtain the list of key sets associated with the given fabric.
     *  In order to release the allocated memory, the Release() method must be called after the iteration is finished.
     *  Modifying the key sets table during the iteration is currently not supported, and may yield unexpected behaviour.
     *
     *  @retval An instance of KeySetIterator on success
     *  @retval nullptr if no iterator instances are available.
     */
    virtual KeySetIterator * IterateKeySets(FabricIndex fabric_index) = 0;

    // Fabrics
    virtual CHIP_ERROR RemoveFabric(FabricIndex fabric_index) = 0;

    // Decryption
    virtual GroupSessionIterator * IterateGroupSessions(uint16_t session_id)                        = 0;
    virtual Crypto::SymmetricKeyContext * GetKeyContext(FabricIndex fabric_index, GroupId group_id) = 0;

    // Listener
    void SetListener(GroupListener * listener) { mListener = listener; };
    void RemoveListener() { mListener = nullptr; };

protected:
    void GroupAdded(FabricIndex fabric_index, const GroupInfo & new_group)
    {
        if (mListener)
        {
            mListener->OnGroupAdded(fabric_index, new_group);
        }
    }
    void GroupRemoved(FabricIndex fabric_index, const GroupInfo & old_group)
    {
        if (mListener)
        {
            mListener->OnGroupRemoved(fabric_index, old_group);
        }
    }
    const uint16_t mMaxGroupsPerFabric;
    const uint16_t mMaxGroupKeysPerFabric;
    GroupListener * mListener = nullptr;
};

/**
 * @brief Utility Set the IPK Epoch key on a GroupDataProvider assuming a single IPK
 *
 * This utility replaces having to call `GroupDataProvider::SetKeySet` for the simple situation of a
 * single IPK for a fabric, if a single epoch key is used. Start time will be set to 0 ("was always valid")
 *
 * @param provider - pointer to GroupDataProvider on which to set the IPK
 * @param fabric_index - fabric index within the GroupDataProvider for which to set the IPK
 * @param ipk_epoch_span - Span containing the IPK epoch key
 * @param compressed_fabric_id - Compressed fabric ID associated with the fabric, for key derivation
 * @return CHIP_NO_ERROR on success, CHIP_ERROR_INVALID_ARGUMENT on any bad argument, other CHIP_ERROR values
 *         from implementation on other errors
 */
inline CHIP_ERROR SetSingleIpkEpochKey(GroupDataProvider * provider, FabricIndex fabric_index, const ByteSpan & ipk_epoch_span,
                                       const ByteSpan & compressed_fabric_id)
{
    GroupDataProvider::KeySet ipkKeySet(GroupDataProvider::kIdentityProtectionKeySetId,
                                        GroupDataProvider::SecurityPolicy::kTrustFirst, 1);

    VerifyOrReturnError(provider != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(ipk_epoch_span.size() == sizeof(ipkKeySet.epoch_keys[0].key), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(compressed_fabric_id.size() == sizeof(uint64_t), CHIP_ERROR_INVALID_ARGUMENT);

    ipkKeySet.epoch_keys[0].start_time = 0;
    memcpy(&ipkKeySet.epoch_keys[0].key, ipk_epoch_span.data(), ipk_epoch_span.size());

    // Set a single IPK, validate key derivation follows spec
    return provider->SetKeySet(fabric_index, compressed_fabric_id, ipkKeySet);
}

/**
 * Instance getter for the global GroupDataProvider.
 *
 * Callers have to externally synchronize usage of this function.
 *
 * @return The global Group Data Provider
 */
GroupDataProvider * GetGroupDataProvider();

/**
 * Instance setter for the global GroupDataProvider.
 *
 * Callers have to externally synchronize usage of this function.
 *
 * The `provider` can be set to nullptr if the owner is done with it fully.
 *
 * @param[in] provider pointer to the Group Data Provider global isntance to use
 */
void SetGroupDataProvider(GroupDataProvider * provider);

} // namespace Credentials
} // namespace chip
