/*
 *    Copyright (c) 2022 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 <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/Span.h>

namespace chip {
namespace Crypto {

class OperationalKeystore
{
public:
    virtual ~OperationalKeystore() {}

    // ==== API designed for commisionables to support fail-safe (although can be used by controllers) ====

    /**
     * @brief Returns true if a pending operational key exists from a previous
     *        `NewOpKeypairForFabric` before any `CommitOpKeypairForFabric` or
     *        `RevertOpKeypairForFabric`. This returns true even if the key is
     *        NOT ACTIVE (i.e after `NewOpKeypairForFabric` but before
     *        `ActivateOpKeypairForFabric`).
     */
    virtual bool HasPendingOpKeypair() const = 0;

    /**
     * @brief Returns whether a usable operational key exists for the given fabric.
     *
     * Returns true even if the key is not persisted, such as if `ActivateOpKeypairForFabric`
     * had been successfully called for a given fabric. Only returns true if a key
     * is presently usable such that `SignWithOpKeypair` would succeed for the fabric. Therefore
     * if there was no previously persisted key and `NewOpKeypairForFabric` had been called
     * but not `ActivateOpKeypairForFabric`, there is only an inactive key, and this would return false.
     *
     * @param fabricIndex - FabricIndex for which availability of keypair will be checked.
     * @return true if there an active operational keypair for the given FabricIndex, false otherwise.
     */
    virtual bool HasOpKeypairForFabric(FabricIndex fabricIndex) const = 0;

    /**
     * @brief This initializes a new keypair for the given fabric and generates a CSR for it,
     *        so that it can be passed in a CSRResponse.
     *
     * The keypair is temporary and becomes usable for `SignWithOpKeypair` only after either
     * `ActivateOpKeypairForFabric` is called. It is destroyed if
     * `RevertPendingKeypair` is called before `CommitOpKeypairForFabric`.
     *  If a pending keypair already existed for the given `fabricIndex`, it is replaced by this call.
     *
     *  Only one pending operational keypair is supported at a time.
     *
     * @param fabricIndex - FabricIndex for which a new keypair must be made available
     * @param outCertificateSigningRequest - Buffer to contain the CSR. Must have size at least `kMIN_CSR_Buffer_Size`.
     *
     * @retval CHIP_NO_ERROR on success
     * @retval CHIP_ERROR_BUFFER_TOO_SMALL if `outCertificateSigningRequest` buffer is too small
     * @retval CHIP_ERROR_INCORRECT_STATE if the key store is not properly initialized.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if there is already a pending keypair for another `fabricIndex` value
     *                                         or if fabricIndex is an invalid value.
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if only `SignWithOpKeypair` is supported
     * @retval other CHIP_ERROR value on internal crypto engine errors
     */
    virtual CHIP_ERROR NewOpKeypairForFabric(FabricIndex fabricIndex, MutableByteSpan & outCertificateSigningRequest) = 0;

    /**
     * @brief Temporarily activates the operational keypair last generated with `NewOpKeypairForFabric`, so
     *        that `SignWithOpKeypair` starts using it, but only if it matches the public key associated
     *        with the last NewOpKeypairForFabric.
     *
     * This is to be used by AddNOC and UpdateNOC so that a prior key generated by NewOpKeypairForFabric
     * can be used for CASE while not committing it yet to permanent storage to remain after fail-safe.
     *
     * @param fabricIndex - FabricIndex for which to activate the keypair, used for security cross-checking
     * @param nocPublicKey - Subject public key associated with an incoming NOC
     *
     * @retval CHIP_NO_ERROR on success
     * @retval CHIP_ERROR_INCORRECT_STATE if the key store is not properly initialized.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if there is no operational keypair for `fabricIndex` from a previous
     *                                         matching `NewOpKeypairForFabric`.
     * @retval CHIP_ERROR_INVALID_PUBLIC_KEY if `nocPublicKey` does not match the public key associated with the
     *                                       key pair from last `NewOpKeypairForFabric`.
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if only `SignWithOpKeypair` is supported
     * @retval other CHIP_ERROR value on internal storage or crypto engine errors
     */
    virtual CHIP_ERROR ActivateOpKeypairForFabric(FabricIndex fabricIndex, const Crypto::P256PublicKey & nocPublicKey) = 0;

    /**
     * @brief Permanently commit the operational keypair last generated with `NewOpKeypairForFabric`,
     *        replacing a prior one previously committed, if any, so that `SignWithOpKeypair` for the
     *        given `FabricIndex` permanently uses the key that was pending.
     *
     * This is to be used when CommissioningComplete is successfully received
     *
     * @param fabricIndex - FabricIndex for which to commit the keypair, used for security cross-checking
     *
     * @retval CHIP_NO_ERROR on success
     * @retval CHIP_ERROR_INCORRECT_STATE if the key store is not properly initialized,
     *                                    or ActivateOpKeypairForFabric not yet called
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if there is no pending operational keypair for `fabricIndex`
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if only `SignWithOpKeypair` is supported
     * @retval other CHIP_ERROR value on internal storage or crypto engine errors
     */
    virtual CHIP_ERROR CommitOpKeypairForFabric(FabricIndex fabricIndex) = 0;

    /**
     * @brief Try to read out the permanently committed operational keypair and save it to the buffer.
     *
     * @param fabricIndex - FabricIndex from which the keypair will be exported
     * @param outKeypair - a reference to P256SerializedKeypair object to store the exported key.
     * @retval CHIP_ERROR on success.
     * @retval CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if the key cannot be exported due to security restrictions.
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if the exporting is not implemented for the cryptography backend.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if provided wrong value of `fabricIndex`.
     * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if there is no keypair found for `fabricIndex`.
     * @retval CHIP_ERROR_BUFFER_TOO_SMALL if `outKeyPair` buffer is too small to store the read out keypair.
     * @retval other CHIP_ERROR value on internal storage or cryptography backend errors.
     */
    virtual CHIP_ERROR ExportOpKeypairForFabric(FabricIndex fabricIndex, Crypto::P256SerializedKeypair & outKeypair)
    {
        return CHIP_ERROR_NOT_IMPLEMENTED;
    };

    /**
     * @brief Migrate the operational keypair from another Operational keystore (`operationalKeystore`) implementation to this one.
     *
     * This method assumes that the operational key for given `fabricIndex` exists in the `operationalKeystore` storage or it has
     * been already migrated to the new Operational Storage. If a key for the given `fabricIndex` does not exist in any of those
     * keystores, then the method retuns CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND.
     *
     * @param fabricIndex - FabricIndex for which to migrate the operational key
     * @param operationalKeystore - a reference to the operationalKeystore implementation that may contain saved operational key
     * for Fabric
     * @retval CHIP_ERROR on success
     * @retval CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if the key cannot be exported due to security restrictions.
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if the exporting is not implemented for the cryptography backend.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if there is no keypair found for `fabricIndex`.
     * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if there is no keypair found for `fabricIndex`.
     * @retval other CHIP_ERROR value on internal storage or crypto engine errors.
     */
    virtual CHIP_ERROR MigrateOpKeypairForFabric(FabricIndex fabricIndex, OperationalKeystore & operationalKeystore) const
    {
        return CHIP_ERROR_NOT_IMPLEMENTED;
    };

    /**
     * @brief Permanently remove the keypair associated with a fabric
     *
     * This is to be used for fail-safe handling and RemoveFabric.  Removes both the
     * pending operational keypair for the fabricIndex (if any) and the committed one (if any).
     *
     * @param fabricIndex - FabricIndex for which to remove the keypair
     *
     * @retval CHIP_NO_ERROR on success
     * @retval CHIP_ERROR_INCORRECT_STATE if the key store is not properly initialized.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if there is no operational keypair for `fabricIndex`
     * @retval CHIP_ERROR_NOT_IMPLEMENTED if only `SignWithOpKeypair` is supported
     * @retval other CHIP_ERROR value on internal storage errors
     */
    virtual CHIP_ERROR RemoveOpKeypairForFabric(FabricIndex fabricIndex) = 0;

    /**
     * @brief Permanently release the operational keypair last generated with `NewOpKeypairForFabric`,
     *        such that `SignWithOpKeypair` uses the previously committed key (if one existed).
     *
     * This is to be used when a fail-safe expires prior to CommissioningComplete.
     *
     * This method cannot error-out and must always succeed, even on a no-op. This should
     * be safe to do given that `CommitOpKeypairForFabric` must succeed to make a new operational
     * keypair usable.
     */
    virtual void RevertPendingKeypair() = 0;

    // ==== Primary operation required: signature
    /**
     * @brief Whether `SignWithOpKeypair` may be performed in the background.
     *
     * If true, `CASESession` may attempt to perform `SignWithOpKeypair` in the
     * background. In this case, `OperationalKeystore` should protect itself,
     * e.g. with a mutex, as the signing could occur at any time during session
     * establishment.
     *
     * @retval true if `SignWithOpKeypair` may be performed in the background
     * @retval false if `SignWithOpKeypair` may NOT be performed in the background
     */
    virtual bool SupportsSignWithOpKeypairInBackground() const { return false; }

    /**
     * @brief Sign a message with a fabric's currently-active operational keypair.
     *
     * If a Keypair was successfully made temporarily active for the given `fabricIndex` with `ActivateOpKeypairForFabric`,
     * then that is the keypair whose private key is used. Otherwise, the last committed private key
     * is used, if one exists
     *
     * @param fabricIndex - FabricIndex whose operational keypair will be used to sign the `message`
     * @param message - Message to sign with the currently active operational keypair
     * @param outSignature - Buffer to contain the signature
     *
     * @retval CHIP_NO_ERROR on success
     * @retval CHIP_ERROR_INCORRECT_STATE if the key store is not properly initialized.
     * @retval CHIP_ERROR_INVALID_FABRIC_INDEX if no active key is found for the given `fabricIndex` or if
     *                                         `fabricIndex` is invalid.
     * @retval other CHIP_ERROR value on internal crypto engine errors
     */
    virtual CHIP_ERROR SignWithOpKeypair(FabricIndex fabricIndex, const ByteSpan & message,
                                         Crypto::P256ECDSASignature & outSignature) const = 0;

    /**
     * @brief Create an ephemeral keypair for use in session establishment.
     *
     * The caller must Initialize() the P256Keypair if needed. It is not done by this method.
     *
     * This method MUST ONLY be used for CASESession ephemeral keys.
     *
     * NOTE: The stack will allocate as many of these as there are CASE sessions which
     *       can be concurrently in the process of establishment. Implementations must
     *       support more than one such keypair, or be implemented to match the limitations
     *       enforced by a given product on its concurrent CASE session establishment limits.
     *
     * WARNING: The return value MUST be released by `ReleaseEphemeralKeypair`. This is because
     *          Matter CHIPMem.h does not properly support UniquePtr in a way that would
     *          safely allow classes derived from Crypto::P256Keypair to be released properly.
     *
     * @return a pointer to a P256Keypair (or derived class thereof), which may evaluate to nullptr
     *         if running out of memory.
     */
    virtual Crypto::P256Keypair * AllocateEphemeralKeypairForCASE() = 0;

    /**
     * @brief Release an ephemeral keypair previously provided by `AllocateEphemeralKeypairForCASE()`
     */
    virtual void ReleaseEphemeralKeypair(Crypto::P256Keypair * keypair) = 0;
};

} // namespace Crypto
} // namespace chip
