/*
 *
 *    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 <algorithm>
#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)
        {
            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)
        {
            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, Optional<GroupId> group_id = NullOptional) = 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
