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

#include <app/clusters/diagnostic-logs-server/diagnostic-logs-server.h>
#include <app/server/Server.h>
#include <app/util/util.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <lib/core/CHIPError.h>
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/logging/CHIPLogging.h>

#include <fstream>
#include <iostream>
#include <unistd.h>

using chip::BitFlags;
using chip::ArgParser::HelpOptions;
using chip::ArgParser::OptionDef;
using chip::ArgParser::OptionSet;
using chip::ArgParser::PrintArgError;
using chip::Messaging::ExchangeManager;

bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
{
    // No option yet
    return true;
}

OptionDef cmdLineOptionsDef[] = {
    {},
};

OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS" };

HelpOptions helpOptions("log-source-app", "Usage: log-source-app [options]", "1.0");

OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr };

static constexpr size_t kMaxLogMessageLength = 512;

DiagnosticLogsCommandHandler & GetLogProvider()
{
    static DiagnosticLogsCommandHandler LogProvider;
    return LogProvider;
}

void LoggingCallback(const char * module, uint8_t category, const char * msg, va_list args)
{
    // Print the log on console for debug
    va_list argsCopy;
    va_copy(argsCopy, args);
    chip::Logging::Platform::LogV(module, category, msg, argsCopy);

    // Feed the log entry into the internal circular buffer
    char buffer1[kMaxLogMessageLength];
    char buffer2[kMaxLogMessageLength];
    int s1 = vsnprintf(buffer1, sizeof(buffer1), msg, args);
    int s2 = snprintf(buffer2, sizeof(buffer2), "%s:%.*s", module, s1, buffer1);
    GetLogProvider().PushLog(chip::ByteSpan(reinterpret_cast<uint8_t *>(buffer2), s2));
}

int main(int argc, char * argv[])
{
    if (chip::Platform::MemoryInit() != CHIP_NO_ERROR)
    {
        fprintf(stderr, "FAILED to initialize memory\n");
        return 1;
    }

    chip::Logging::SetLogRedirectCallback(&LoggingCallback);

    if (chip::DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR)
    {
        fprintf(stderr, "FAILED to initialize chip stack\n");
        return 1;
    }

    if (!chip::ArgParser::ParseArgs(argv[0], argc, argv, allOptions))
    {
        return 1;
    }

    chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig();
    chip::Server::GetInstance().Init();

    // Initialize device attestation config
    SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());

    chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(&GetLogProvider());

    chip::DeviceLayer::PlatformMgr().RunEventLoop();

    return 0;
}
