/*
 *
 *    Copyright (c) 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/basic-types.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPCallback.h>
#include <lib/core/PeerId.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Span.h>
#include <transport/raw/MessageHeader.h>

namespace chip {
namespace Controller {

typedef void (*OnNOCChainGeneration)(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
                                     const ByteSpan & rcac, Optional<Crypto::AesCcm128KeySpan> ipk, Optional<NodeId> adminSubject);

constexpr uint32_t kMaxCHIPDERCertLength = 600;
constexpr size_t kCSRNonceLength         = 32;

/// Callbacks for CHIP operational credentials generation
class DLL_EXPORT OperationalCredentialsDelegate
{
public:
    virtual ~OperationalCredentialsDelegate() {}

    /**
     * @brief
     *   This function generates an operational certificate chain for a remote device that is being commissioned.
     *   The API generates the certificate in X.509 DER format.
     *
     *   The delegate is expected to use the certificate authority whose certificate
     *   is returned in `GetRootCACertificate()` API call.
     *
     *   The delegate will call `onCompletion` when the NOC certificate chain is ready.
     *
     * @param[in] csrElements          CSR elements as per specifications section 11.18.5.6. NOCSR Elements.
     * @param[in] csrNonce             CSR nonce as described in 6.4.6.1
     * @param[in] attestationSignature Attestation signature as per specifications section 11.22.7.6. CSRResponse Command.
     * @param[in] attestationChallenge Attestation challenge as per 11.18.5.7
     * @param[in] DAC                  Device attestation certificate received from the device being commissioned
     * @param[in] PAI                  Product Attestation Intermediate certificate
     * @param[in] onCompletion         Callback handler to provide generated NOC chain to the caller of GenerateNOCChain()
     *
     * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
     */
    virtual CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce,
                                        const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge,
                                        const ByteSpan & DAC, const ByteSpan & PAI,
                                        Callback::Callback<OnNOCChainGeneration> * onCompletion) = 0;

    /**
     *   This function sets the node ID for which the next NOC Chain would be requested. The node ID is
     *   provided as a hint, and the delegate implementation may chose to ignore it and pick node ID of
     *   their choice.
     */
    virtual void SetNodeIdForNextNOCRequest(NodeId nodeId) {}

    /**
     *   This function sets the fabric ID for which the next NOC Chain should be generated. This API is
     *   not required to be implemented if the delegate implementation has other mechanisms to find the
     *   fabric ID.
     */
    virtual void SetFabricIdForNextNOCRequest(FabricId fabricId) {}

    virtual CHIP_ERROR ObtainCsrNonce(MutableByteSpan & csrNonce)
    {
        VerifyOrReturnError(csrNonce.size() == kCSRNonceLength, CHIP_ERROR_INVALID_ARGUMENT);
        ReturnErrorOnFailure(Crypto::DRBG_get_bytes(csrNonce.data(), csrNonce.size()));
        return CHIP_NO_ERROR;
    }
};

} // namespace Controller
} // namespace chip
