/*
 *
 *    Copyright (c) 2022 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 "OTAHelper.h"

#include <app/clusters/ota-requestor/BDXDownloader.h>
#include <app/clusters/ota-requestor/DefaultOTARequestor.h>
#include <app/clusters/ota-requestor/DefaultOTARequestorStorage.h>
#include <app/clusters/ota-requestor/ExtendedOTARequestorDriver.h>
#include <platform/ESP32/OTAImageProcessorImpl.h>
#include <system/SystemEvent.h>

#include <app/clusters/ota-requestor/DefaultOTARequestorUserConsent.h>
#include <lib/shell/Commands.h>
#include <lib/shell/Engine.h>
#include <lib/shell/commands/Help.h>
#include <lib/support/logging/CHIPLogging.h>

using namespace chip::DeviceLayer;
using namespace chip;

class CustomOTARequestorDriver : public DeviceLayer::ExtendedOTARequestorDriver
{
public:
    bool CanConsent() override;
};

namespace {
DefaultOTARequestor gRequestorCore;
DefaultOTARequestorStorage gRequestorStorage;
CustomOTARequestorDriver gRequestorUser;
BDXDownloader gDownloader;
OTAImageProcessorImpl gImageProcessor;
chip::Optional<bool> gRequestorCanConsent;
static chip::ota::UserConsentState gUserConsentState = chip::ota::UserConsentState::kUnknown;
chip::ota::DefaultOTARequestorUserConsent gUserConsentProvider;

} // namespace

bool CustomOTARequestorDriver::CanConsent()
{
    return gRequestorCanConsent.ValueOr(DeviceLayer::ExtendedOTARequestorDriver::CanConsent());
}

static void InitOTARequestorHandler(System::Layer * systemLayer, void * appState)
{
    SetRequestorInstance(&gRequestorCore);
    gRequestorStorage.Init(Server::GetInstance().GetPersistentStorage());
    gRequestorCore.Init(Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader);
    gImageProcessor.SetOTADownloader(&gDownloader);
    gDownloader.SetImageProcessorDelegate(&gImageProcessor);
    gRequestorUser.Init(&gRequestorCore, &gImageProcessor);

    if (gUserConsentState != chip::ota::UserConsentState::kUnknown)
    {
        gUserConsentProvider.SetUserConsentState(gUserConsentState);
        gRequestorUser.SetUserConsentDelegate(&gUserConsentProvider);
    }
}

void OTAHelpers::InitOTARequestor()
{
    chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(kInitOTARequestorDelaySec), InitOTARequestorHandler,
                                                nullptr);
}

namespace chip {
namespace Shell {
namespace {

Shell::Engine sSubShell;

CHIP_ERROR UserConsentStateHandler(int argc, char ** argv)
{
    VerifyOrReturnError(argc == 1, CHIP_ERROR_INVALID_ARGUMENT);

    if (strcmp(argv[0], "granted") == 0)
    {
        gUserConsentState = chip::ota::UserConsentState::kGranted;
    }
    else if (strcmp(argv[0], "denied") == 0)
    {
        gUserConsentState = chip::ota::UserConsentState::kDenied;
    }
    else if (strcmp(argv[0], "deferred") == 0)
    {
        gUserConsentState = chip::ota::UserConsentState::kObtaining;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR RequestorCanConsentHandler(int argc, char ** argv)
{
    VerifyOrReturnError(argc == 1, CHIP_ERROR_INVALID_ARGUMENT);

    if (strcmp(argv[0], "true") == 0)
    {
        gRequestorCanConsent.SetValue(true);
    }
    else if (strcmp(argv[0], "false") == 0)
    {
        gRequestorCanConsent.SetValue(false);
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR SetPeriodicQueryTimeoutHandler(int argc, char ** argv)
{
    VerifyOrReturnError(argc == 1, CHIP_ERROR_INVALID_ARGUMENT);
    gRequestorUser.SetPeriodicQueryTimeout(strtoul(argv[0], NULL, 0));
    gRequestorUser.RekickPeriodicQueryTimer();
    return CHIP_NO_ERROR;
}

CHIP_ERROR OTARequestorHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        sSubShell.ForEachCommand(PrintCommandHelp, nullptr);
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR error = sSubShell.ExecCommand(argc, argv);

    if (error != CHIP_NO_ERROR)
    {
        streamer_printf(streamer_get(), "Error: %" CHIP_ERROR_FORMAT "\r\n", error.Format());
    }

    return error;
}
} // namespace

void OTARequestorCommands::Register()
{
    // Register subcommands of the `OTARequestor` commands.
    static const shell_command_t subCommands[] = {
        { &UserConsentStateHandler, "userConsentState",
          "Set UserConsentState for QueryImageCommand\n"
          "Usage: OTARequestor userConsentState <granted/denied/deferred>" },
        { &RequestorCanConsentHandler, "requestorCanConsent",
          "Set requestorCanConsent for QueryImageCommand\n"
          "Usage: OTARequestor requestorCanConsent <true/false>" },
        { &SetPeriodicQueryTimeoutHandler, "PeriodicQueryTimeout",
          "Set timeout for querying the OTA provider for an update\n"
          "Usage: OTARequestor PeriodicQueryTimeout <seconds>" },

    };

    sSubShell.RegisterCommands(subCommands, ArraySize(subCommands));

    // Register the root `OTA Requestor` command in the top-level shell.
    static const shell_command_t otaRequestorCommand = { &OTARequestorHandler, "OTARequestor", "OTA Requestor commands" };

    Engine::Root().RegisterCommands(&otaRequestorCommand, 1);
}

} // namespace Shell
} // namespace chip
