/*
 *
 *    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 <AppMain.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/PlatformManager.h>

#include <app-common/zap-generated/af-structs.h>

#include <app-common/zap-generated/attribute-id.h>
#include <app/ConcreteAttributePath.h>
#include <app/EventLogging.h>
#include <app/chip-zcl-zpro-codec.h>
#include <app/reporting/reporting.h>
#include <app/util/af-types.h>
#include <app/util/af.h>
#include <app/util/attribute-storage.h>
#include <app/util/util.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <lib/core/CHIPError.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/ZclString.h>
#include <platform/CommissionableDataProvider.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>

#include "ActionCluster.h"
#include "Backend.h"
#include "CommissionableInit.h"
#include "Device.h"
#include "main.h"
#include <app/server/Server.h>

#include "AppMain.h"

#include "bridge/BridgeClustersImpl.h"

#ifdef PW_RPC_ENABLED
#include "Rpc.h"
#include "bridge_service.h"
#include "pw_rpc_system_server/rpc_server.h"
static chip::rpc::Bridge bridge_service;
#endif

#include <cassert>
#include <iostream>
#include <vector>

using namespace chip;
using namespace chip::Credentials;
using namespace chip::Inet;
using namespace chip::Transport;
using namespace chip::DeviceLayer;
using namespace chip::app::Clusters;

static EndpointId gCurrentEndpointId;
static EndpointId gFirstDynamicEndpointId;
static Device * gDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
Room gRooms[kMaxRooms];

struct CommonAttributeAccessInterface : public chip::app::AttributeAccessInterface
{
    using chip::app::AttributeAccessInterface::AttributeAccessInterface;

    // Find a cluster given a specific endpoint/cluster. Returns nullptr if no such
    // cluster exists at that path.
    static CommonCluster * FindCluster(const chip::app::ConcreteClusterPath & path);

    CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & aPath, chip::app::AttributeValueEncoder & aEncoder) override;
    CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & aPath, chip::app::AttributeValueDecoder & aDecoder) override;

    void OnListWriteBegin(const chip::app::ConcreteAttributePath & aPath) override;
    void OnListWriteEnd(const chip::app::ConcreteAttributePath & aPath, bool aWriteWasSuccessful) override;
};

CommonCluster * CommonAttributeAccessInterface::FindCluster(const chip::app::ConcreteClusterPath & path)
{
    Device * dev = FindDeviceEndpoint(path.mEndpointId);
    if (dev)
    {
        for (auto c : dev->clusters())
        {
            if (c->GetClusterId() == path.mClusterId)
                return static_cast<CommonCluster *>(c);
        }
    }
    return nullptr;
}

CHIP_ERROR CommonAttributeAccessInterface::Read(const chip::app::ConcreteReadAttributePath & aPath,
                                                chip::app::AttributeValueEncoder & aEncoder)
{
    CommonCluster * c = FindCluster(aPath);
    if (!c)
        return CHIP_ERROR_NOT_IMPLEMENTED;
    AttributeInterface * a = c->FindAttribute(aPath.mAttributeId);
    if (!a)
        return CHIP_ERROR_NOT_IMPLEMENTED;
    return a->Read(aPath, aEncoder);
}

CHIP_ERROR CommonAttributeAccessInterface::Write(const chip::app::ConcreteDataAttributePath & aPath,
                                                 chip::app::AttributeValueDecoder & aDecoder)
{
    CommonCluster * c = FindCluster(aPath);
    if (!c)
        return CHIP_ERROR_NOT_IMPLEMENTED;
    return c->ForwardWriteToBridge(aPath, aDecoder);
}

void CommonAttributeAccessInterface::OnListWriteBegin(const chip::app::ConcreteAttributePath & aPath)
{
    CommonCluster * c = FindCluster(aPath);
    if (c)
    {
        AttributeInterface * a = c->FindAttribute(aPath.mAttributeId);
        if (a)
            a->ListWriteBegin(aPath);
    }
}

void CommonAttributeAccessInterface::OnListWriteEnd(const chip::app::ConcreteAttributePath & aPath, bool aWriteWasSuccessful)
{
    CommonCluster * c = FindCluster(aPath);
    if (c)
    {
        AttributeInterface * a = c->FindAttribute(aPath.mAttributeId);
        if (a)
            a->ListWriteEnd(aPath, aWriteWasSuccessful);
    }
}

chip::Optional<chip::ClusterId> LookupClusterByName(const char * name)
{
    for (const auto & cluster : clusters::kKnownClusters)
    {
        if (!strcmp(name, cluster.name))
        {
            return chip::Optional<chip::ClusterId>(cluster.id);
        }
    }
    return chip::Optional<chip::ClusterId>();
}

std::unique_ptr<GeneratedCluster> CreateCluster(const char * name)
{
    auto id = LookupClusterByName(name);
    return id.HasValue() ? CreateCluster(id.Value()) : nullptr;
}

std::unique_ptr<GeneratedCluster> CreateCluster(chip::ClusterId id)
{
    for (const auto & cluster : clusters::kKnownClusters)
    {
        if (id == cluster.id)
        {
            return std::unique_ptr<GeneratedCluster>(cluster.ctor(::operator new(cluster.size)));
        }
    }
    return nullptr;
}

bool emberAfActionsClusterInstantActionCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                const Actions::Commands::InstantAction::DecodableType & commandData)
{
    // No actions are implemented, just return status NotFound.
    commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::NotFound);
    return true;
}

Device * FindDeviceEndpoint(chip::EndpointId id)
{
    for (auto dev : gDevices)
    {
        if (dev && dev->GetEndpointId() == id)
            return dev;
    }
    return nullptr;
}

int AddDeviceEndpoint(Device * dev)
{
    uint8_t index = 0;
    while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
    {
        if (nullptr == gDevices[index])
        {
            gDevices[index] = dev;
            EmberAfStatus ret;
            while (true)
            {
                // Todo: Update this to schedule the work rather than use this lock
                dev->SetEndpointId(gCurrentEndpointId);
                ret =
                    emberAfSetDynamicEndpoint(index, gCurrentEndpointId, dev->endpointType(), dev->versions(), dev->deviceTypes());
                if (ret == EMBER_ZCL_STATUS_SUCCESS)
                {
                    ChipLogProgress(DeviceLayer, "Added device %s to dynamic endpoint %d (index=%d)", dev->GetName(),
                                    gCurrentEndpointId, index);
                    return index;
                }
                if (ret != EMBER_ZCL_STATUS_DUPLICATE_EXISTS)
                {
                    ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: %d!", ret);
                    gDevices[index] = nullptr;
                    return -1;
                }
                // Handle wrap condition
                if (++gCurrentEndpointId < gFirstDynamicEndpointId)
                {
                    gCurrentEndpointId = gFirstDynamicEndpointId;
                }
            }
        }
        index++;
    }
    ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: No endpoints available!");
    return -1;
}

int RemoveDeviceEndpoint(Device * dev)
{
    uint8_t index = 0;
    while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
    {
        if (gDevices[index] == dev)
        {
            // Todo: Update this to schedule the work rather than use this lock
            DeviceLayer::StackLock lock;
            EndpointId ep   = emberAfClearDynamicEndpoint(index);
            gDevices[index] = nullptr;
            ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index);
            // Silence complaints about unused ep when progress logging
            // disabled.
            UNUSED_VAR(ep);
            return index;
        }
        index++;
    }
    return -1;
}

Room * FindRoom(const std::string & name)
{
    for (auto & room : gRooms)
    {
        if (room.GetName() == name)
            return &room;
    }
    return nullptr;
}

chip::Span<Action *> GetActionListInfo(chip::EndpointId parentId)
{
    return chip::Span<Action *>();
}

void ApplicationInit()
{
#ifdef PW_RPC_ENABLED
    chip::rpc::Init();

    pw::rpc::system_server::Server().RegisterService(bridge_service);
#endif

    gFirstDynamicEndpointId = static_cast<chip::EndpointId>(
        static_cast<int>(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1))) + 1);
    gCurrentEndpointId = gFirstDynamicEndpointId;
    StartUserInput();
}

int main(int argc, char * argv[])
{
    VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);

    std::vector<CommonAttributeAccessInterface> clusterAccess;
    clusterAccess.reserve(std::extent<decltype(clusters::kKnownClusters)>::value);
    for (auto & entry : clusters::kKnownClusters)
    {
        // Desciptor clusters should not be overridden.
        if (entry.id != chip::app::Clusters::Descriptor::Id)
        {
            clusterAccess.emplace_back(chip::Optional<EndpointId>(), entry.id);
            registerAttributeAccessOverride(&clusterAccess.back());
        }
    }

    ChipLinuxAppMainLoop();
    return 0;
}
