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

using namespace ::chip;

namespace admin {

namespace {

constexpr uint32_t kCommissionPrepareTimeMs = 500;

} // namespace

FabricAdmin FabricAdmin::sInstance;

FabricAdmin & FabricAdmin::Instance()
{
    if (!sInstance.mInitialized)
    {
        sInstance.Init();
    }
    return sInstance;
}

CHIP_ERROR
FabricAdmin::CommissionRemoteBridge(Controller::CommissioningWindowPasscodeParams params, VendorId vendorId, uint16_t productId)
{
    char saltHex[Crypto::kSpake2p_Max_PBKDF_Salt_Length * 2 + 1];
    Encoding::BytesToHex(params.GetSalt().data(), params.GetSalt().size(), saltHex, sizeof(saltHex),
                         Encoding::HexFlags::kNullTerminate);

    ChipLogProgress(NotSpecified, "Received CommissionNode request");

    SetupPayload setupPayload = SetupPayload();

    setupPayload.setUpPINCode = params.GetSetupPIN();
    setupPayload.version      = 0;
    setupPayload.vendorID     = vendorId;
    setupPayload.productID    = productId;
    setupPayload.rendezvousInformation.SetValue(RendezvousInformationFlag::kOnNetwork);

    SetupDiscriminator discriminator{};
    discriminator.SetLongValue(params.GetDiscriminator());
    setupPayload.discriminator = discriminator;

    QRCodeSetupPayloadGenerator generator(setupPayload);
    std::string code;
    CHIP_ERROR err = generator.payloadBase38RepresentationWithAutoTLVBuffer(code);

    if (err == CHIP_NO_ERROR)
    {
        NodeId nodeId = DeviceMgr().GetNextAvailableNodeId();

        // After responding with RequestCommissioningApproval to the node where the client initiated the
        // RequestCommissioningApproval, you need to wait for it to open a commissioning window on its bridge.
        usleep(kCommissionPrepareTimeMs * 1000);

        DeviceMgr().PairRemoteDevice(nodeId, code.c_str());
    }
    else
    {
        ChipLogError(NotSpecified, "Unable to generate pairing code for setup payload: %" CHIP_ERROR_FORMAT, err.Format());
        return err;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR FabricAdmin::KeepActive(ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs)
{
    ChipLogProgress(NotSpecified, "Received KeepActive request: Id[%d, 0x" ChipLogFormatX64 "], %u", scopedNodeId.GetFabricIndex(),
                    ChipLogValueX64(scopedNodeId.GetNodeId()), stayActiveDurationMs);

    KeepActiveWorkData * data = Platform::New<KeepActiveWorkData>(this, scopedNodeId, stayActiveDurationMs, timeoutMs);
    VerifyOrReturnError(data != nullptr, CHIP_ERROR_NO_MEMORY);

    DeviceLayer::PlatformMgr().ScheduleWork(KeepActiveWork, reinterpret_cast<intptr_t>(data));
    return CHIP_NO_ERROR;
}

void FabricAdmin::ScheduleSendingKeepActiveOnCheckIn(ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs)
{
    // Accessing mPendingCheckIn should only be done while holding ChipStackLock
    assertChipStackLockedByCurrentThread();

    auto timeNow                             = System::SystemClock().GetMonotonicTimestamp();
    System::Clock::Timestamp expiryTimestamp = timeNow + System::Clock::Milliseconds64(timeoutMs);
    KeepActiveDataForCheckIn checkInData     = { .mStayActiveDurationMs   = stayActiveDurationMs,
                                                 .mRequestExpiryTimestamp = expiryTimestamp };

    auto it = mPendingCheckIn.find(scopedNodeId);
    if (it != mPendingCheckIn.end())
    {
        checkInData.mStayActiveDurationMs   = std::max(checkInData.mStayActiveDurationMs, it->second.mStayActiveDurationMs);
        checkInData.mRequestExpiryTimestamp = std::max(checkInData.mRequestExpiryTimestamp, it->second.mRequestExpiryTimestamp);
    }

    mPendingCheckIn[scopedNodeId] = checkInData;
}

} // namespace admin
