/*
 *
 *    Copyright (c) 2022-2023 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/util/ember-compatibility-functions.h>

#include <access/SubjectDescriptor.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>
#include <app/CommandHandler.h>
#include <app/ConcreteAttributePath.h>
#include <app/ConcreteCommandPath.h>
#include <app/GlobalAttributes.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/MessageDef/StatusIB.h>
#include <app/WriteHandler.h>
#include <app/data-model/Decode.h>
#include <app/util/att-storage.h>
#include <app/util/endpoint-config-api.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/Optional.h>
#include <lib/core/TLV.h>
#include <protocols/interaction_model/Constants.h>

/**
 * This file defines the APIs needed to handle interaction model dispatch.
 * These are the APIs normally defined in
 * src/app/util/ember-compatibility-functions.cpp and the generated
 * IMClusterCommandHandler.cpp but we want a different implementation of these
 * to enable more dynamic behavior, since not all framework consumers will be
 * implementing the same server clusters.
 */
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;

namespace {

// TODO: Maybe consider making this configurable?  See also
// AccessControl.cpp.
constexpr EndpointId kSupportedEndpoint = 0;

} // anonymous namespace

namespace chip {
namespace app {

using Access::SubjectDescriptor;
using Protocols::InteractionModel::Status;

namespace {

bool IsSupportedGlobalAttribute(AttributeId aAttribute)
{
    // We don't have any non-global attributes.
    using namespace Globals::Attributes;

    for (auto & attr : GlobalAttributesNotInMetadata)
    {
        if (attr == aAttribute)
        {
            return true;
        }
    }

    switch (aAttribute)
    {
    case FeatureMap::Id:
        FALLTHROUGH;
    case ClusterRevision::Id:
        return true;
    }

    return false;
}

Status DetermineAttributeStatus(const ConcreteAttributePath & aPath, bool aIsWrite)
{
    // TODO: Consider making this configurable for applications that are not
    // trying to be an OTA provider, though in practice it just affects which
    // error is returned.
    if (aPath.mEndpointId != kSupportedEndpoint)
    {
        return Status::UnsupportedEndpoint;
    }

    // TODO: Consider making this configurable for applications that are not
    // trying to be an OTA provider, though in practice it just affects which
    // error is returned.
    if (aPath.mClusterId != OtaSoftwareUpdateProvider::Id)
    {
        return Status::UnsupportedCluster;
    }

    if (!IsSupportedGlobalAttribute(aPath.mAttributeId))
    {
        return Status::UnsupportedAttribute;
    }

    // No permissions for this for read, and none of these are writable for
    // write.  The writable-or-not check happens before the ACL check.
    return aIsWrite ? Status::UnsupportedWrite : Status::UnsupportedAccess;
}

} // anonymous namespace

CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered,
                                 const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports,
                                 AttributeEncodeState * aEncoderState)
{
    Status status = DetermineAttributeStatus(aPath, /* aIsWrite = */ false);
    return aAttributeReports.EncodeAttributeStatus(aPath, StatusIB(status));
}

bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath)
{
    return DetermineAttributeStatus(aPath, /* aIsWrite = */ false) == Status::UnsupportedAccess;
}

Status ServerClusterCommandExists(const ConcreteCommandPath & aPath)
{
    // TODO: Consider making this configurable for applications that are not
    // trying to be an OTA provider.
    using namespace OtaSoftwareUpdateProvider::Commands;

    if (aPath.mEndpointId != kSupportedEndpoint)
    {
        return Status::UnsupportedEndpoint;
    }

    if (aPath.mClusterId != OtaSoftwareUpdateProvider::Id)
    {
        return Status::UnsupportedCluster;
    }

    switch (aPath.mCommandId)
    {
    case QueryImage::Id:
        FALLTHROUGH;
    case ApplyUpdateRequest::Id:
        FALLTHROUGH;
    case NotifyUpdateApplied::Id:
        return Status::Success;
    }

    return Status::UnsupportedCommand;
}

bool IsClusterDataVersionEqual(const ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion)
{
    // Will never be called anyway; we have no attributes.
    return false;
}

const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath)
{
    // Note: This test does not make use of the real attribute metadata.
    static EmberAfAttributeMetadata stub = { .defaultValue = EmberAfDefaultOrMinMaxAttributeValue(uint32_t(0)) };
    return &stub;
}

bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint)
{
    return false;
}

CHIP_ERROR WriteSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, const ConcreteDataAttributePath & aPath,
                                  TLV::TLVReader & aReader, WriteHandler * aWriteHandler)
{
    Status status = DetermineAttributeStatus(aPath, /* aIsWrite = */ true);
    return aWriteHandler->AddStatus(aPath, status);
}

void DispatchSingleClusterCommand(const ConcreteCommandPath & aPath, TLV::TLVReader & aReader, CommandHandler * aCommandObj)
{
    // This command passed ServerClusterCommandExists so we know it's one of our
    // supported commands.
    using namespace OtaSoftwareUpdateProvider::Commands;

    bool wasHandled = false;
    CHIP_ERROR err  = CHIP_NO_ERROR;

    switch (aPath.mCommandId)
    {
    case QueryImage::Id: {
        QueryImage::DecodableType commandData;
        err = DataModel::Decode(aReader, commandData);
        if (err == CHIP_NO_ERROR)
        {
            wasHandled = emberAfOtaSoftwareUpdateProviderClusterQueryImageCallback(aCommandObj, aPath, commandData);
        }
        break;
    }
    case ApplyUpdateRequest::Id: {
        ApplyUpdateRequest::DecodableType commandData;
        err = DataModel::Decode(aReader, commandData);
        if (err == CHIP_NO_ERROR)
        {
            wasHandled = emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestCallback(aCommandObj, aPath, commandData);
        }
        break;
    }
    case NotifyUpdateApplied::Id: {
        NotifyUpdateApplied::DecodableType commandData;
        err = DataModel::Decode(aReader, commandData);
        if (err == CHIP_NO_ERROR)
        {
            wasHandled = emberAfOtaSoftwareUpdateProviderClusterNotifyUpdateAppliedCallback(aCommandObj, aPath, commandData);
        }
        break;
    }
    default:
        break;
    }

    if (CHIP_NO_ERROR != err || !wasHandled)
    {
        aCommandObj->AddStatus(aPath, Status::InvalidCommand);
    }
}

Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath)
{
    return Protocols::InteractionModel::Status::UnsupportedEvent;
}

} // namespace app
} // namespace chip

/**
 * Called by the OTA provider cluster server to determine an index
 * into its array.
 */
uint16_t emberAfGetClusterServerEndpointIndex(EndpointId endpoint, ClusterId cluster, uint16_t fixedClusterServerEndpointCount)
{
    if (endpoint == kSupportedEndpoint && cluster == OtaSoftwareUpdateProvider::Id)
    {
        return 0;
    }

    return UINT16_MAX;
}

/**
 * Methods used by AttributePathExpandIterator, which need to exist
 * because it is part of libCHIP.  For AttributePathExpandIterator
 * purposes, for now, we just pretend like we have just our one
 * endpoint, the OTA Provider cluster, and no attributes (because we
 * would be erroring out from them anyway).
 */
uint16_t emberAfGetServerAttributeCount(EndpointId endpoint, ClusterId cluster)
{
    return 0;
}

uint16_t emberAfEndpointCount(void)
{
    return 1;
}

uint16_t emberAfIndexFromEndpoint(EndpointId endpoint)
{
    if (endpoint == kSupportedEndpoint)
    {
        return 0;
    }

    return UINT16_MAX;
}

EndpointId emberAfEndpointFromIndex(uint16_t index)
{
    // Index must be valid here, so 0.
    return kSupportedEndpoint;
}

Optional<ClusterId> emberAfGetNthClusterId(EndpointId endpoint, uint8_t n, bool server)
{
    if (endpoint == kSupportedEndpoint && n == 0 && server)
    {
        return MakeOptional(OtaSoftwareUpdateProvider::Id);
    }

    return NullOptional;
}

uint16_t emberAfGetServerAttributeIndexByAttributeId(EndpointId endpoint, ClusterId cluster, AttributeId attributeId)
{
    return UINT16_MAX;
}

bool emberAfContainsAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId)
{
    return false;
}

uint8_t emberAfClusterCount(EndpointId endpoint, bool server)
{
    if (endpoint == kSupportedEndpoint && server)
    {
        return 1;
    }

    return 0;
}

Optional<AttributeId> emberAfGetServerAttributeIdByIndex(EndpointId endpoint, ClusterId cluster, uint16_t attributeIndex)
{
    return NullOptional;
}

uint8_t emberAfClusterIndex(EndpointId endpoint, ClusterId clusterId, EmberAfClusterMask mask)
{
    if (endpoint == kSupportedEndpoint && clusterId == OtaSoftwareUpdateProvider::Id && (mask & CLUSTER_MASK_SERVER))
    {
        return 0;
    }

    return UINT8_MAX;
}

bool emberAfEndpointIndexIsEnabled(uint16_t index)
{
    return index == 0;
}

namespace {
const CommandId acceptedCommands[]  = { Clusters::OtaSoftwareUpdateProvider::Commands::QueryImage::Id,
                                        Clusters::OtaSoftwareUpdateProvider::Commands::ApplyUpdateRequest::Id,
                                        Clusters::OtaSoftwareUpdateProvider::Commands::NotifyUpdateApplied::Id, kInvalidCommandId };
const CommandId generatedCommands[] = { Clusters::OtaSoftwareUpdateProvider::Commands::QueryImageResponse::Id,
                                        Clusters::OtaSoftwareUpdateProvider::Commands::ApplyUpdateResponse::Id, kInvalidCommandId };
const EmberAfCluster otaProviderCluster{
    .clusterId            = Clusters::OtaSoftwareUpdateProvider::Id,
    .attributes           = nullptr,
    .attributeCount       = 0,
    .clusterSize          = 0,
    .mask                 = CLUSTER_MASK_SERVER,
    .functions            = nullptr,
    .acceptedCommandList  = acceptedCommands,
    .generatedCommandList = generatedCommands,
    .eventList            = nullptr,
    .eventCount           = 0,
};
const EmberAfEndpointType otaProviderEndpoint{ .cluster = &otaProviderCluster, .clusterCount = 1, .endpointSize = 0 };
} // namespace

const EmberAfEndpointType * emberAfFindEndpointType(EndpointId endpoint)
{
    if (endpoint == kSupportedEndpoint)
    {
        return &otaProviderEndpoint;
    }

    return nullptr;
}

const EmberAfCluster * emberAfFindServerCluster(EndpointId endpoint, ClusterId cluster)
{
    if (endpoint == kSupportedEndpoint && cluster == Clusters::OtaSoftwareUpdateProvider::Id)
    {
        return &otaProviderCluster;
    }

    return nullptr;
}
