/*
 *
 *    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.
 */

#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/util/af.h>
#include <app/util/error-mapping.h>
#include <platform/CHIPDeviceConfig.h>
#include <protocols/interaction_model/Constants.h>

#include <lib/support/Span.h>

#include "ota-provider-delegate.h"
#include "ota-provider.h"

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::OtaSoftwareUpdateProvider;
using chip::app::Clusters::OTAProviderDelegate;
using Protocols::InteractionModel::Status;

// EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT is only defined if the
// cluster is actually enabled in the ZAP config.  To allow operation in setups
// where that's not the case (and custom dispatch is used), define it here as
// needed.
#ifndef EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT
#define EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT 0
#endif // EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT

static constexpr size_t kOtaProviderDelegateTableSize =
    EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

namespace {
constexpr size_t kLocationLen          = 2;   // The expected length of the location parameter in QueryImage
constexpr size_t kMaxMetadataLen       = 512; // The maximum length of Metadata in any OTA Provider command
constexpr size_t kUpdateTokenMaxLength = 32;  // The expected length of the Update Token parameter used in multiple commands
constexpr size_t kUpdateTokenMinLength = 8;   // The expected length of the Update Token parameter used in multiple commands

OTAProviderDelegate * gDelegateTable[kOtaProviderDelegateTableSize] = { nullptr };

OTAProviderDelegate * GetDelegate(EndpointId endpoint)
{
    uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, OtaSoftwareUpdateProvider::Id);
    return (ep == 0xFFFF ? nullptr : gDelegateTable[ep]);
}

bool SendStatusIfDelegateNull(app::CommandHandler * commandObj, const app::ConcreteCommandPath & path)
{
    if (GetDelegate(path.mEndpointId) == nullptr)
    {
        ChipLogError(Zcl, "No OTAProviderDelegate set for ep:%u", path.mEndpointId);
        commandObj->AddStatus(path, Status::UnsupportedCommand);
        return true;
    }
    return false;
}
} // namespace

/**
 * @brief OTA Software Update Provider Cluster ApplyUpdateRequest Command callback
 *
 * @note It is the application's reponsibility to send the ApplyUpdateRequestResponse command after this is handled.
 */
bool emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestCallback(
    app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
    const Commands::ApplyUpdateRequest::DecodableType & commandData)
{
    auto & updateToken             = commandData.updateToken;
    EndpointId endpoint            = commandPath.mEndpointId;
    OTAProviderDelegate * delegate = GetDelegate(endpoint);

    ChipLogProgress(Zcl, "OTA Provider received ApplyUpdateRequest");
    ChipLogDetail(Zcl, "  Update Token: %u", static_cast<unsigned int>(commandData.updateToken.size()));
    ChipLogDetail(Zcl, "  New Version: %" PRIu32, commandData.newVersion);

    if (SendStatusIfDelegateNull(commandObj, commandPath))
    {
        return true;
    }

    if (updateToken.size() > kUpdateTokenMaxLength || updateToken.size() < kUpdateTokenMinLength)
    {
        ChipLogError(Zcl, "expected size %u for UpdateToken, got %u", static_cast<unsigned int>(kUpdateTokenMaxLength),
                     static_cast<unsigned int>(updateToken.size()));
        commandObj->AddStatus(commandPath, Status::InvalidCommand);
        return true;
    }

    delegate->HandleApplyUpdateRequest(commandObj, commandPath, commandData);

    return true;
}

/**
 * @brief OTA Software Update Provider Cluster NotifyUpdateApplied Command callback
 */
bool emberAfOtaSoftwareUpdateProviderClusterNotifyUpdateAppliedCallback(
    app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
    const Commands::NotifyUpdateApplied::DecodableType & commandData)
{
    auto & updateToken             = commandData.updateToken;
    EndpointId endpoint            = commandPath.mEndpointId;
    OTAProviderDelegate * delegate = GetDelegate(endpoint);

    ChipLogProgress(Zcl, "OTA Provider received NotifyUpdateApplied");
    ChipLogDetail(Zcl, "  Update Token: %u", static_cast<unsigned int>(commandData.updateToken.size()));
    ChipLogDetail(Zcl, "  Software Version: %" PRIu32, commandData.softwareVersion);

    if (SendStatusIfDelegateNull(commandObj, commandPath))
    {
        return true;
    }

    if (updateToken.size() > kUpdateTokenMaxLength || updateToken.size() < kUpdateTokenMinLength)
    {
        ChipLogError(Zcl, "expected size %u for UpdateToken, got %u", static_cast<unsigned int>(kUpdateTokenMaxLength),
                     static_cast<unsigned int>(updateToken.size()));
        commandObj->AddStatus(commandPath, Status::InvalidCommand);
        return true;
    }

    delegate->HandleNotifyUpdateApplied(commandObj, commandPath, commandData);

    return true;
}

/**
 * @brief OTA Software Update Provider Cluster QueryImage Command callback
 */
bool emberAfOtaSoftwareUpdateProviderClusterQueryImageCallback(app::CommandHandler * commandObj,
                                                               const app::ConcreteCommandPath & commandPath,
                                                               const Commands::QueryImage::DecodableType & commandData)
{
    auto & vendorId            = commandData.vendorId;
    auto & productId           = commandData.productId;
    auto & hardwareVersion     = commandData.hardwareVersion;
    auto & softwareVersion     = commandData.softwareVersion;
    auto & protocolsSupported  = commandData.protocolsSupported;
    auto & location            = commandData.location;
    auto & requestorCanConsent = commandData.requestorCanConsent;
    auto & metadataForProvider = commandData.metadataForProvider;

    (void) vendorId;
    (void) productId;
    (void) softwareVersion;

    EndpointId endpoint            = commandPath.mEndpointId;
    OTAProviderDelegate * delegate = GetDelegate(endpoint);

    if (SendStatusIfDelegateNull(commandObj, commandPath))
    {
        return true;
    };

    ChipLogProgress(Zcl, "OTA Provider received QueryImage");
    ChipLogDetail(Zcl, "  VendorID: 0x%x", vendorId);
    ChipLogDetail(Zcl, "  ProductID: %u", productId);
    ChipLogDetail(Zcl, "  SoftwareVersion: %" PRIu32, softwareVersion);
    ChipLogDetail(Zcl, "  ProtocolsSupported: [");
    auto protocolIter = protocolsSupported.begin();
    while (protocolIter.Next())
    {
        ChipLogDetail(Zcl, "    %u", to_underlying(protocolIter.GetValue()));
    }
    ChipLogDetail(Zcl, "  ]");
    if (hardwareVersion.HasValue())
    {
        ChipLogDetail(Zcl, "  HardwareVersion: %u", hardwareVersion.Value());
    }
    if (location.HasValue())
    {
        ChipLogDetail(Zcl, "  Location: %.*s", static_cast<int>(location.Value().size()), location.Value().data());
    }
    if (requestorCanConsent.HasValue())
    {
        ChipLogDetail(Zcl, "  RequestorCanConsent: %u", requestorCanConsent.Value());
    }
    if (metadataForProvider.HasValue())
    {
        ChipLogDetail(Zcl, "  MetadataForProvider: %u", static_cast<unsigned int>(metadataForProvider.Value().size()));
    }

    if (location.HasValue() && location.Value().size() != kLocationLen)
    {
        ChipLogError(Zcl, "location param length %u != expected length %u", static_cast<unsigned int>(location.Value().size()),
                     static_cast<unsigned int>(kLocationLen));
        commandObj->AddStatus(commandPath, Status::InvalidCommand);
        return true;
    }

    if (metadataForProvider.HasValue() && metadataForProvider.Value().size() > kMaxMetadataLen)
    {
        ChipLogError(Zcl, "metadata size %u exceeds max %u", static_cast<unsigned int>(metadataForProvider.Value().size()),
                     static_cast<unsigned int>(kMaxMetadataLen));
        commandObj->AddStatus(commandPath, Status::InvalidCommand);
        return true;
    }

    delegate->HandleQueryImage(commandObj, commandPath, commandData);

    return true;
}

namespace chip {
namespace app {
namespace Clusters {
namespace OTAProvider {

void SetDelegate(EndpointId endpoint, OTAProviderDelegate * delegate)
{
    uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, OtaSoftwareUpdateProvider::Id);
    if (ep != 0xFFFF)
    {
        gDelegateTable[ep] = delegate;
    }
}

} // namespace OTAProvider
} // namespace Clusters
} // namespace app
} // namespace chip

void MatterOtaSoftwareUpdateProviderPluginServerInitCallback() {}
