/*
 *    Copyright (c) 2024-2026 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.
 */

#include "CommissionerControlDelegate.h"

#include <app-common/zap-generated/cluster-objects.h>
#include <app/clusters/commissioner-control-server/commissioner-control-server.h>
#include <controller/CommissioningWindowOpener.h>
#include <lib/support/ZclString.h>
#include <protocols/interaction_model/StatusCode.h>
#include <protocols/secure_channel/PASESession.h>

using namespace chip;
using namespace chip::app;

namespace {

// Constants
constexpr uint16_t kDiscriminator = 3840;
constexpr uint16_t kWindowTimeout = 300;
constexpr uint16_t kIteration     = 1000;
constexpr uint32_t kSetupPinCode  = 20202021;

std::unique_ptr<Clusters::CommissionerControl::CommissionerControlDelegate> sCommissionerControlDelegate;

} // namespace

namespace chip {
namespace app {
namespace Clusters {
namespace CommissionerControl {

void CommissionerControlDelegate::ResetDelegateState()
{
    ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Resetting delegate state");

    // Reset the step to the initial state
    mNextStep = Step::kIdle;

    // Reset identifiers and product information
    mRequestId    = 0;
    mClientNodeId = kUndefinedNodeId;
    mVendorId     = VendorId::Unspecified;
    mProductId    = 0;

    // Clear the label buffer and optional label
    memset(mLabelBuffer, 0, sizeof(mLabelBuffer));
    mLabel.ClearValue();

    // Reset PBKDF salt and PAKE passcode verifier buffers
    mPBKDFSalt = ByteSpan();
    memset(mPBKDFSaltBuffer, 0, sizeof(mPBKDFSaltBuffer));

    mPAKEPasscodeVerifier = ByteSpan();
    memset(mPAKEPasscodeVerifierBuffer, 0, sizeof(mPAKEPasscodeVerifierBuffer));
}

CHIP_ERROR CommissionerControlDelegate::HandleCommissioningApprovalRequest(const CommissioningApprovalRequest & request)
{
    ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering HandleCommissioningApprovalRequest, current state: %s",
                    GetStateString(mNextStep));

    VerifyOrReturnError(mNextStep == Step::kIdle, CHIP_ERROR_INCORRECT_STATE);

    CommissionerControl::Events::CommissioningRequestResult::Type result;
    result.requestID    = request.requestId;
    result.clientNodeID = request.clientNodeId;
    result.fabricIndex  = request.fabricIndex;
    result.statusCode   = static_cast<uint8_t>(Protocols::InteractionModel::Status::Success);

    mRequestId    = request.requestId;
    mClientNodeId = request.clientNodeId;
    mVendorId     = request.vendorId;
    mProductId    = request.productId;

    if (request.label.HasValue())
    {
        const CharSpan & labelSpan = request.label.Value();
        size_t labelLength         = labelSpan.size();

        if (labelLength >= kLabelBufferSize)
        {
            ChipLogError(Zcl, "Label too long to fit in buffer");
            return CHIP_ERROR_BUFFER_TOO_SMALL;
        }

        if (labelLength == 0)
        {
            mLabel.ClearValue();
        }
        else
        {
            memcpy(mLabelBuffer, labelSpan.data(), labelLength);
            mLabelBuffer[labelLength] = '\0'; // Null-terminate the copied string
            mLabel.SetValue(CharSpan(mLabelBuffer, labelLength));
        }
    }
    else
    {
        mLabel.ClearValue();
    }

    CHIP_ERROR err = mCommissionerControlServer.GenerateCommissioningRequestResultEvent(kAggregatorEndpointId, result);

    if (err == CHIP_NO_ERROR)
    {
        mNextStep = Step::kWaitCommissionNodeRequest;
        ChipLogProgress(NotSpecified, "CommissionerControlDelegate: State transitioned to %s", GetStateString(mNextStep));
    }
    else
    {
        ResetDelegateState();
    }

    return err;
}

CHIP_ERROR CommissionerControlDelegate::ValidateCommissionNodeCommand(NodeId clientNodeId, uint64_t requestId)
{
    ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering ValidateCommissionNodeCommand, current state: %s",
                    GetStateString(mNextStep));

    CHIP_ERROR err = CHIP_NO_ERROR;

    VerifyOrReturnError(mNextStep == Step::kWaitCommissionNodeRequest, CHIP_ERROR_INCORRECT_STATE);

    // Verify if the CommissionNode command is sent from the same NodeId as the RequestCommissioningApproval.
    VerifyOrExit(mClientNodeId == clientNodeId, err = CHIP_ERROR_WRONG_NODE_ID);

    // Verify if the provided RequestId matches the value provided to the RequestCommissioningApproval.
    VerifyOrExit(mRequestId == requestId, err = CHIP_ERROR_INCORRECT_STATE);

    mNextStep = Step::kStartCommissionNode;
    ChipLogProgress(NotSpecified, "CommissionerControlDelegate: State transitioned to %s", GetStateString(mNextStep));

exit:
    return err;
}

CHIP_ERROR CommissionerControlDelegate::GetCommissioningWindowParams(CommissioningWindowParams & outParams)
{
    // Populate outParams with the required details.
    outParams.iterations           = kIteration;
    outParams.commissioningTimeout = kWindowTimeout;
    outParams.discriminator        = kDiscriminator;

    ReturnErrorOnFailure(Crypto::DRBG_get_bytes(mPBKDFSaltBuffer, sizeof(mPBKDFSaltBuffer)));
    mPBKDFSalt     = ByteSpan(mPBKDFSaltBuffer);
    outParams.salt = mPBKDFSalt;

    Crypto::Spake2pVerifier verifier;
    uint32_t setupPIN = kSetupPinCode;
    ReturnErrorOnFailure(PASESession::GeneratePASEVerifier(verifier, kIteration, mPBKDFSalt, false, setupPIN));

    MutableByteSpan serializedVerifierSpan(mPAKEPasscodeVerifierBuffer);
    ReturnErrorOnFailure(verifier.Serialize(serializedVerifierSpan));
    mPAKEPasscodeVerifier          = serializedVerifierSpan;
    outParams.PAKEPasscodeVerifier = mPAKEPasscodeVerifier;

    return CHIP_NO_ERROR;
}

CHIP_ERROR CommissionerControlDelegate::HandleCommissionNode(const CommissioningWindowParams & params)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    ChipLogProgress(NotSpecified, "CommissionerControlDelegate: Entering HandleCommissionNode, current state: %s",
                    GetStateString(mNextStep));

    VerifyOrReturnError(mNextStep == Step::kStartCommissionNode, CHIP_ERROR_INCORRECT_STATE);

    // Attempt to reverse commission the bridge using provided commissioning parameters.
    err = mFabricAdmin->CommissionRemoteBridge(Controller::CommissioningWindowPasscodeParams()
                                                   .SetSetupPIN(kSetupPinCode)
                                                   .SetTimeout(params.commissioningTimeout)
                                                   .SetDiscriminator(params.discriminator)
                                                   .SetIteration(params.iterations)
                                                   .SetSalt(params.salt),
                                               mVendorId, mProductId);

    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(NotSpecified, "Failed to reverse commission the fabric bridge. Error: %" CHIP_ERROR_FORMAT, err.Format());
    }

    // Reset the delegate's state to prepare for a new commissioning sequence.
    ResetDelegateState();

    return err;
}

} // namespace CommissionerControl
} // namespace Clusters
} // namespace app
} // namespace chip

namespace bridge {

CHIP_ERROR CommissionerControlInit(bridge::FabricAdminDelegate * fabricAdmin)
{
    CHIP_ERROR err;

    if (sCommissionerControlDelegate)
    {
        ChipLogError(NotSpecified, "Commissioner Control Delegate already exists.");
        return CHIP_ERROR_INCORRECT_STATE;
    }

    sCommissionerControlDelegate = std::make_unique<Clusters::CommissionerControl::CommissionerControlDelegate>(fabricAdmin);
    if (!sCommissionerControlDelegate)
    {
        ChipLogError(NotSpecified, "Failed to allocate memory for Commissioner Control Delegate.");
        return CHIP_ERROR_NO_MEMORY;
    }

    err = sCommissionerControlDelegate->GetCommissionerControlServer().Init();
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(AppServer, "Initialization failed on Commissioner Control Delegate.");
        sCommissionerControlDelegate.reset();
        return err;
    }

    ChipLogProgress(Zcl, "Initializing SupportedDeviceCategories of Commissioner Control Cluster for this device.");

    BitMask<Clusters::CommissionerControl::SupportedDeviceCategoryBitmap> supportedDeviceCategories;
    supportedDeviceCategories.SetField(Clusters::CommissionerControl::SupportedDeviceCategoryBitmap::kFabricSynchronization, 1);

    Protocols::InteractionModel::Status status =
        sCommissionerControlDelegate->GetCommissionerControlServer().SetSupportedDeviceCategoriesValue(
            Clusters::CommissionerControl::kAggregatorEndpointId, supportedDeviceCategories);

    if (status != Protocols::InteractionModel::Status::Success)
    {
        ChipLogError(NotSpecified, "Failed to set SupportedDeviceCategories: %d", static_cast<int>(status));
        sCommissionerControlDelegate.reset();
        return CHIP_ERROR_INTERNAL;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR CommissionerControlShutdown()
{
    if (sCommissionerControlDelegate)
    {
        sCommissionerControlDelegate.reset();
    }

    return CHIP_NO_ERROR;
}

} // namespace bridge
