/*
 *
 *    Copyright (c) 2022 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.
 */
#import <Foundation/Foundation.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/AttributeAccessInterface.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/att-storage.h>
#include <app/data-model/Decode.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
// CHIPControllerAccessControl.mm.
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,
        AttributeValueEncoder::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);
    }

    // No attribute access overrides on iOS for now.
    // TODO (#16806): This function can be moved to InteractionModelEngine.
    AttributeAccessInterface * GetAttributeAccessOverride(EndpointId endpointId, ClusterId clusterId) { return nullptr; }

    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);
        }
    }

} // namespace app
} // namespace chip

/**
 * Called by the OTA provider cluster server to determine an index
 * into its array.
 */
uint16_t emberAfFindClusterServerEndpointIndex(EndpointId endpoint, ClusterId clusterId)
{
    if (endpoint == kSupportedEndpoint && clusterId == 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; }
