/**
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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/cluster-objects.h>
#include <app/CommandHandler.h>
#include <app/CommandHandlerInterface.h>
#include <app/ConcreteCommandPath.h>
#include <app/clusters/diagnostic-logs-server/diagnostic-logs-server.h>
#include <app/util/af.h>
#include <lib/support/BytesCircularBuffer.h>

#include <array>

CHIP_ERROR DiagnosticLogsCommandHandler::PushLog(const chip::ByteSpan & payload)
{
    chip::System::Clock::Milliseconds32 now = chip::System::SystemClock().GetMonotonicTimestamp();
    uint32_t timeMs                         = now.count();
    chip::ByteSpan payloadTime(reinterpret_cast<uint8_t *>(&timeMs), sizeof(timeMs));
    return mBuffer.Push(payloadTime, payload);
}

void DiagnosticLogsCommandHandler::InvokeCommand(HandlerContext & handlerContext)
{
    HandleCommand<chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsRequest::DecodableType>(
        handlerContext, [&](auto & _u, auto & payload) {
            if (payload.requestedProtocol == chip::app::Clusters::DiagnosticLogs::LogsTransferProtocol::kUnknownEnumValue)
            {
                handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath,
                                                         chip::Protocols::InteractionModel::Status::InvalidCommand);
                return;
            }

            switch (payload.intent)
            {
            case chip::app::Clusters::DiagnosticLogs::LogsIntent::kEndUserSupport: {
                chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsResponse::Type response;
                if (mBuffer.IsEmpty())
                {
                    response.status = chip::app::Clusters::DiagnosticLogs::LogsStatus::kNoLogs;
                    handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, response);
                    break;
                }

                size_t logSize = mBuffer.GetFrontSize();
                chip::System::Clock::Milliseconds32::rep timeMs;
                VerifyOrDie(logSize > sizeof(timeMs));

                std::unique_ptr<uint8_t, decltype(&chip::Platform::MemoryFree)> buf(
                    reinterpret_cast<uint8_t *>(chip::Platform::MemoryAlloc(logSize)), &chip::Platform::MemoryFree);
                if (!buf)
                {
                    response.status = chip::app::Clusters::DiagnosticLogs::LogsStatus::kBusy;
                    handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, response);
                    break;
                }

                // The entry is | time (4 bytes) | content (var size) |
                chip::MutableByteSpan entry(buf.get(), logSize);
                CHIP_ERROR err = mBuffer.ReadFront(entry);
                VerifyOrDie(err == CHIP_NO_ERROR);
                timeMs = *reinterpret_cast<decltype(timeMs) *>(buf.get());

                response.status    = chip::app::Clusters::DiagnosticLogs::LogsStatus::kSuccess;
                response.content   = chip::ByteSpan(buf.get() + sizeof(timeMs), logSize - sizeof(timeMs));
                response.timeStamp = timeMs;
                handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, response);
            }
            break;
            case chip::app::Clusters::DiagnosticLogs::LogsIntent::kNetworkDiag: {
                chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsResponse::Type response;
                response.status = chip::app::Clusters::DiagnosticLogs::LogsStatus::kNoLogs;
                handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, response);
            }
            break;
            case chip::app::Clusters::DiagnosticLogs::LogsIntent::kCrashLogs: {
                chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsResponse::Type response;
                response.status = chip::app::Clusters::DiagnosticLogs::LogsStatus::kNoLogs;
                handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, response);
            }
            break;
            case chip::app::Clusters::DiagnosticLogs::LogsIntent::kUnknownEnumValue: {
                handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath,
                                                         chip::Protocols::InteractionModel::Status::InvalidCommand);
                break;
            }
            }
        });
}

bool emberAfDiagnosticLogsClusterRetrieveLogsRequestCallback(
    chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
    const chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsRequest::DecodableType & commandData)
{
    // TODO: Shouldn't the default "no-op" impl return some sort of error?
    EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
    emberAfSendImmediateDefaultResponse(status);
    return true;
}

void MatterDiagnosticLogsPluginServerInitCallback() {}
