/*
 *
 *    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 "nvs_flash.h"

#include <lib/shell/Engine.h>

#include <lib/core/CHIPCore.h>
#include <lib/support/Base64.h>
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

#include <ChipShellCollection.h>
#include <lib/support/CHIPMem.h>
#include <platform/CHIPDeviceLayer.h>

#include <app/clusters/network-commissioning/network-commissioning.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>

#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <platform/ESP32/ESP32Utils.h>
#include <platform/ESP32/NetworkCommissioningDriver.h>

#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/att-storage.h>
#include <app/server/Dnssd.h>
#include <app/util/af.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>

#include "Display.h"
#include "QRCodeScreen.h"
#include "ScreenManager.h"

#if CONFIG_ENABLE_PW_RPC
#include "Rpc.h"
#endif /* CONFIG_ENABLE_PW_RPC */

using namespace chip;
using namespace chip::Shell;
using chip::Shell::Engine;
using namespace chip::DeviceLayer;

#if CONFIG_ENABLE_CHIP_SHELL
static void chip_shell_task(void * args)
{

    cmd_misc_init();

    Engine::Root().RunMainLoop();
}
#endif /* CONFIG_ENABLE_CHIP_SHELL */

void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg)
{
    switch (event->Type)
    {
    case DeviceEventType::kInternetConnectivityChange:
        if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established)
        {
            ChipLogProgress(Shell, "IPv4 Server ready...");
            chip::app::DnssdServer::Instance().StartServer();
        }
        else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost)
        {
            ChipLogProgress(Shell, "Lost IPv4 connectivity...");
        }
        if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established)
        {
            ChipLogProgress(Shell, "IPv6 Server ready...");
            chip::app::DnssdServer::Instance().StartServer();
        }
        else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost)
        {
            ChipLogProgress(Shell, "Lost IPv6 connectivity...");
        }

        break;

    case DeviceEventType::kCHIPoBLEConnectionEstablished:
        ChipLogProgress(Shell, "CHIPoBLE connection established");
        break;

    case DeviceEventType::kCHIPoBLEConnectionClosed:
        ChipLogProgress(Shell, "CHIPoBLE disconnected");
        break;

    case DeviceEventType::kCommissioningComplete:
        ChipLogProgress(Shell, "Commissioning complete");
        break;

    case DeviceEventType::kInterfaceIpAddressChanged:
        if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) ||
            (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned))
        {
            // DNSSD server restart on any ip assignment: if link local ipv6 is configured, that
            // will not trigger a 'internet connectivity change' as there is no internet
            // connectivity. DNSSD still wants to refresh its listening interfaces to include the
            // newly selected address.
            chip::app::DnssdServer::Instance().StartServer();
        }
        break;
    }

    ChipLogProgress(Shell, "Current free heap: %u\n", static_cast<unsigned int>(heap_caps_get_free_size(MALLOC_CAP_8BIT)));
}

const char * TAG = "chef-app";

#if CONFIG_HAVE_DISPLAY
void printQRCode()
{
    // Create buffer for QR code that can fit max size and null terminator.
    char qrCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
    chip::MutableCharSpan qrCodeText(qrCodeBuffer);

    GetQRCode(qrCodeText, chip::RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE));

    // Initialize the display device.
    esp_err_t err = InitDisplay();
    if (err != ESP_OK)
    {
        ChipLogError(Shell, "InitDisplay() failed: %s", esp_err_to_name(err));
        return;
    }

    // Initialize the screen manager
    ScreenManager::Init();

    ESP_LOGI(TAG, "Opening QR code screen");
    ESP_LOGI(TAG, "QR CODE Text: '%s'", qrCodeText.data());
    ScreenManager::PushScreen(chip::Platform::New<QRCodeScreen>(qrCodeText.data()));
}
#endif // CONFIG_HAVE_DISPLAY

app::Clusters::NetworkCommissioning::Instance
    sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPWiFiDriver::GetInstance()));

void InitServer(intptr_t)
{
    // Start IM server
    static chip::CommonCaseDeviceServerInitParams initParams;
    (void) initParams.InitializeStaticResourcesBeforeServerInit();
    chip::Server::GetInstance().Init(initParams);

    // Device Attestation & Onboarding codes
    chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
    sWiFiNetworkCommissioningInstance.Init();
    chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig();

    if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR)
    {
        ChipLogError(Shell, "OpenBasicCommissioningWindow() failed");
    }

    // Register a function to receive events from the CHIP device layer.  Note that calls to
    // this function will happen on the CHIP event loop thread, not the app_main thread.
    PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast<intptr_t>(nullptr));
}

extern "C" void app_main(void)
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    chip::Platform::MemoryInit();
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
    if (DeviceLayer::Internal::ESP32Utils::InitWiFiStack() != CHIP_NO_ERROR)
    {
        ESP_LOGE(TAG, "Failed to initialize the Wi-Fi stack");
        return;
    }
#endif
    chip::DeviceLayer::PlatformMgr().InitChipStack();
    chip::DeviceLayer::PlatformMgr().StartEventLoopTask();

#if CONFIG_ENABLE_CHIP_SHELL
    int ret = Engine::Root().Init();
    VerifyOrDie(ret == 0);
#endif /* CONFIG_ENABLE_CHIP_SHELL */

    // Network connectivity
    // Note to integration: StartWiFiManagement does not exist on ESP32

    chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer);
    PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE));

#if CONFIG_HAVE_DISPLAY
    printQRCode();
#endif // CONFIG_HAVE_DISPLAY

#if CONFIG_ENABLE_PW_RPC
    chip::rpc::Init();
#endif // CONFIG_ENABLE_PW_RPC

#if CONFIG_ENABLE_CHIP_SHELL
    xTaskCreate(&chip_shell_task, "chip_shell", 8192, NULL, 5, NULL);
#endif /* CONFIG_ENABLE_CHIP_SHELL */

    while (true)
    {
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}
