/*
 *
 *    Copyright (c) 2021-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 <app/TestEventTriggerDelegate.h>
#include <app/TimerDelegates.h>
#include <app/reporting/ReportSchedulerImpl.h>
#include <app/server/CommissioningWindowManager.h>
#include <app/server/Server.h>
#include <crypto/RandUtils.h>
#include <lib/dnssd/Advertiser.h>
#include <lib/support/Span.h>
#include <lib/support/UnitTestRegistration.h>
#include <messaging/tests/echo/common.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/CommissionableDataProvider.h>
#include <platform/ConfigurationManager.h>
#include <platform/PlatformManager.h>
#include <platform/TestOnlyCommissionableDataProvider.h>
#include <protocols/secure_channel/PASESession.h>

#include <nlunit-test.h>

using namespace chip::Crypto;

using chip::CommissioningWindowAdvertisement;
using chip::CommissioningWindowManager;
using chip::Server;

// Mock function for linking
void InitDataModelHandler() {}

namespace {
bool sAdminFabricIndexDirty = false;
bool sAdminVendorIdDirty    = false;
bool sWindowStatusDirty     = false;

void ResetDirtyFlags()
{
    sAdminFabricIndexDirty = false;
    sAdminVendorIdDirty    = false;
    sWindowStatusDirty     = false;
}

} // namespace

void MatterReportingAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId)
{
    using namespace chip::app::Clusters;
    using namespace chip::app::Clusters::AdministratorCommissioning::Attributes;
    if (endpoint != chip::kRootEndpointId || clusterId != AdministratorCommissioning::Id)
    {
        return;
    }

    switch (attributeId)
    {
    case WindowStatus::Id:
        sWindowStatusDirty = true;
        break;
    case AdminVendorId::Id:
        sAdminVendorIdDirty = true;
        break;
    case AdminFabricIndex::Id:
        sAdminFabricIndexDirty = true;
        break;
    default:
        break;
    }
}

namespace {

static constexpr int kTestTaskWaitSeconds = 2;

void InitializeChip(nlTestSuite * suite)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    err            = chip::Platform::MemoryInit();
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    err = chip::DeviceLayer::PlatformMgr().InitChipStack();
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);

    static chip::DeviceLayer::TestOnlyCommissionableDataProvider commissionableDataProvider;
    chip::DeviceLayer::SetCommissionableDataProvider(&commissionableDataProvider);

    static chip::CommonCaseDeviceServerInitParams initParams;
    // Report scheduler and timer delegate instance
    static chip::app::DefaultTimerDelegate sTimerDelegate;
    static chip::app::reporting::ReportSchedulerImpl sReportScheduler(&sTimerDelegate);
    initParams.reportScheduler = &sReportScheduler;
    static chip::SimpleTestEventTriggerDelegate sSimpleTestEventTriggerDelegate;
    initParams.testEventTriggerDelegate = &sSimpleTestEventTriggerDelegate;
    (void) initParams.InitializeStaticResourcesBeforeServerInit();
    // Set a randomized server port(slightly shifted from CHIP_PORT) for testing
    initParams.operationalServicePort = static_cast<uint16_t>(initParams.operationalServicePort + chip::Crypto::GetRandU16() % 20);

    err = chip::Server::GetInstance().Init(initParams);

    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);

    Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow();
    chip::DeviceLayer::PlatformMgr().StartEventLoopTask();
}

void ShutdownChipTest()
{
    chip::DeviceLayer::PlatformMgr().StopEventLoopTask();
    chip::DeviceLayer::PlatformMgr().Shutdown();

    auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
    mdnsAdvertiser.RemoveServices();
    mdnsAdvertiser.Shutdown();

    // Server shudown will be called in TearDownTask

    // TODO: At this point UDP endpoits still seem leaked and the sanitizer
    // builds will attempt a memory free. As a result, we keep Memory initialized
    // so that the global UDPManager can still be destructed without a coredump.
    //
    // This is likely either a missing shutdown or an actual UDP endpoint leak
    // which I have not been able to track down yet.
    //
    // chip::Platform::MemoryShutdown();
}

void CheckCommissioningWindowManagerBasicWindowOpenCloseTask(intptr_t context)
{
    nlTestSuite * suite = reinterpret_cast<nlTestSuite *>(context);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    CHIP_ERROR err                             = commissionMgr.OpenBasicCommissioningWindow(commissionMgr.MaxCommissioningTimeout(),
                                                                                            CommissioningWindowAdvertisement::kDnssdOnly);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerFabricIndex().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerVendorId().IsNull());
    NL_TEST_ASSERT(suite, !chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled());
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    commissionMgr.CloseCommissioningWindow();
    NL_TEST_ASSERT(suite, !commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);
}

void CheckCommissioningWindowManagerBasicWindowOpenClose(nlTestSuite * suite, void *)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissioningWindowManagerBasicWindowOpenCloseTask,
                                                  reinterpret_cast<intptr_t>(suite));
    sleep(kTestTaskWaitSeconds);
}

void CheckCommissioningWindowManagerBasicWindowOpenCloseFromClusterTask(intptr_t context)
{
    nlTestSuite * suite = reinterpret_cast<nlTestSuite *>(context);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    constexpr auto fabricIndex                 = static_cast<chip::FabricIndex>(1);
    constexpr auto vendorId                    = static_cast<chip::VendorId>(0xFFF3);
    CHIP_ERROR err                             = commissionMgr.OpenBasicCommissioningWindowForAdministratorCommissioningCluster(
        commissionMgr.MaxCommissioningTimeout(), fabricIndex, vendorId);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kBasicWindowOpen);
    NL_TEST_ASSERT(suite, !commissionMgr.GetOpenerFabricIndex().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerFabricIndex().Value() == fabricIndex);
    NL_TEST_ASSERT(suite, !commissionMgr.GetOpenerVendorId().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerVendorId().Value() == vendorId);
    NL_TEST_ASSERT(suite, !chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled());
    NL_TEST_ASSERT(suite, sWindowStatusDirty);
    NL_TEST_ASSERT(suite, sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, sAdminVendorIdDirty);

    ResetDirtyFlags();
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    commissionMgr.CloseCommissioningWindow();
    NL_TEST_ASSERT(suite, !commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerFabricIndex().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerVendorId().IsNull());
    NL_TEST_ASSERT(suite, sWindowStatusDirty);
    NL_TEST_ASSERT(suite, sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, sAdminVendorIdDirty);

    ResetDirtyFlags();
}

void CheckCommissioningWindowManagerBasicWindowOpenCloseFromCluster(nlTestSuite * suite, void *)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissioningWindowManagerBasicWindowOpenCloseFromClusterTask,
                                                  reinterpret_cast<intptr_t>(suite));
    sleep(kTestTaskWaitSeconds);
}

void CheckCommissioningWindowManagerWindowClosedTask(chip::System::Layer *, void * context)
{
    nlTestSuite * suite                        = static_cast<nlTestSuite *>(context);
    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    NL_TEST_ASSERT(suite, !commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);
}

void CheckCommissioningWindowManagerWindowTimeoutTask(intptr_t context)
{
    nlTestSuite * suite = reinterpret_cast<nlTestSuite *>(context);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    constexpr auto kTimeoutSeconds             = chip::System::Clock::Seconds32(1);
    constexpr uint16_t kTimeoutMs              = 1000;
    constexpr unsigned kSleepPadding           = 100;
    commissionMgr.OverrideMinCommissioningTimeout(kTimeoutSeconds);
    CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(kTimeoutSeconds, CommissioningWindowAdvertisement::kDnssdOnly);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, !chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled());
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(kTimeoutMs + kSleepPadding),
                                                CheckCommissioningWindowManagerWindowClosedTask, suite);
}

void CheckCommissioningWindowManagerWindowTimeout(nlTestSuite * suite, void *)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissioningWindowManagerWindowTimeoutTask,
                                                  reinterpret_cast<intptr_t>(suite));
    sleep(kTestTaskWaitSeconds);
}

void SimulateFailedSessionEstablishmentTask(chip::System::Layer *, void * context)
{
    nlTestSuite * suite                        = static_cast<nlTestSuite *>(context);
    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    commissionMgr.OnSessionEstablishmentStarted();
    commissionMgr.OnSessionEstablishmentError(CHIP_ERROR_INTERNAL);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);
}

void CheckCommissioningWindowManagerWindowTimeoutWithSessionEstablishmentErrorsTask(intptr_t context)
{
    nlTestSuite * suite = reinterpret_cast<nlTestSuite *>(context);
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    constexpr auto kTimeoutSeconds             = chip::System::Clock::Seconds16(1);
    constexpr uint16_t kTimeoutMs              = 1000;
    constexpr unsigned kSleepPadding           = 100;
    CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(kTimeoutSeconds, CommissioningWindowAdvertisement::kDnssdOnly);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, !chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled());
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(kTimeoutMs + kSleepPadding),
                                                CheckCommissioningWindowManagerWindowClosedTask, suite);
    // Simulate a session establishment error during that window, such that the
    // delay for the error plus the window size exceeds our "timeout + padding" above.
    chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(kTimeoutMs / 4 * 3),
                                                SimulateFailedSessionEstablishmentTask, suite);
}

void CheckCommissioningWindowManagerWindowTimeoutWithSessionEstablishmentErrors(nlTestSuite * suite, void *)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissioningWindowManagerWindowTimeoutWithSessionEstablishmentErrorsTask,
                                                  reinterpret_cast<intptr_t>(suite));
    sleep(kTestTaskWaitSeconds);
}

void CheckCommissioningWindowManagerEnhancedWindowTask(intptr_t context)
{
    nlTestSuite * suite                        = reinterpret_cast<nlTestSuite *>(context);
    CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
    uint16_t originDiscriminator;
    CHIP_ERROR err = chip::DeviceLayer::GetCommissionableDataProvider()->GetSetupDiscriminator(originDiscriminator);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    uint16_t newDiscriminator = static_cast<uint16_t>(originDiscriminator + 1);
    Spake2pVerifier verifier;
    constexpr uint32_t kIterations = kSpake2p_Min_PBKDF_Iterations;
    uint8_t salt[kSpake2p_Min_PBKDF_Salt_Length];
    chip::ByteSpan saltData(salt);

    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    constexpr auto fabricIndex = static_cast<chip::FabricIndex>(1);
    constexpr auto vendorId    = static_cast<chip::VendorId>(0xFFF3);
    err = commissionMgr.OpenEnhancedCommissioningWindow(commissionMgr.MaxCommissioningTimeout(), newDiscriminator, verifier,
                                                        kIterations, saltData, fabricIndex, vendorId);
    NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(suite, commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kEnhancedWindowOpen);
    NL_TEST_ASSERT(suite, !chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled());
    NL_TEST_ASSERT(suite, !commissionMgr.GetOpenerFabricIndex().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerFabricIndex().Value() == fabricIndex);
    NL_TEST_ASSERT(suite, !commissionMgr.GetOpenerVendorId().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerVendorId().Value() == vendorId);
    NL_TEST_ASSERT(suite, sWindowStatusDirty);
    NL_TEST_ASSERT(suite, sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, sAdminVendorIdDirty);

    ResetDirtyFlags();
    NL_TEST_ASSERT(suite, !sWindowStatusDirty);
    NL_TEST_ASSERT(suite, !sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

    commissionMgr.CloseCommissioningWindow();
    NL_TEST_ASSERT(suite, !commissionMgr.IsCommissioningWindowOpen());
    NL_TEST_ASSERT(suite,
                   commissionMgr.CommissioningWindowStatusForCluster() ==
                       chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen);
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerFabricIndex().IsNull());
    NL_TEST_ASSERT(suite, commissionMgr.GetOpenerVendorId().IsNull());
    NL_TEST_ASSERT(suite, sWindowStatusDirty);
    NL_TEST_ASSERT(suite, sAdminFabricIndexDirty);
    NL_TEST_ASSERT(suite, sAdminVendorIdDirty);

    ResetDirtyFlags();
}

void CheckCommissioningWindowManagerEnhancedWindow(nlTestSuite * suite, void *)
{
    chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissioningWindowManagerEnhancedWindowTask,
                                                  reinterpret_cast<intptr_t>(suite));
    sleep(kTestTaskWaitSeconds);
}

void TearDownTask(intptr_t context)
{
    chip::Server::GetInstance().Shutdown();
}

const nlTest sTests[] = {
    NL_TEST_DEF("CheckCommissioningWindowManagerEnhancedWindow", CheckCommissioningWindowManagerEnhancedWindow),
    NL_TEST_DEF("CheckCommissioningWindowManagerBasicWindowOpenClose", CheckCommissioningWindowManagerBasicWindowOpenClose),
    NL_TEST_DEF("CheckCommissioningWindowManagerBasicWindowOpenCloseFromCluster",
                CheckCommissioningWindowManagerBasicWindowOpenCloseFromCluster),
    NL_TEST_DEF("CheckCommissioningWindowManagerWindowTimeout", CheckCommissioningWindowManagerWindowTimeout),
    NL_TEST_DEF("CheckCommissioningWindowManagerWindowTimeoutWithSessionEstablishmentErrors",
                CheckCommissioningWindowManagerWindowTimeoutWithSessionEstablishmentErrors),
    NL_TEST_SENTINEL(),
};

} // namespace

int TestCommissioningWindowManager()
{
    // clang-format off
    nlTestSuite theSuite =
	{
        "CommissioningWindowManager",
        &sTests[0],
        nullptr,
        nullptr
    };
    // clang-format on

    InitializeChip(&theSuite);
    nlTestRunner(&theSuite, nullptr);

    // TODO: The platform memory was intentionally left not deinitialized so that minimal mdns can destruct
    chip::DeviceLayer::PlatformMgr().ScheduleWork(TearDownTask, 0);
    sleep(kTestTaskWaitSeconds);
    ShutdownChipTest();

    return (nlTestRunnerStats(&theSuite));
}

CHIP_REGISTER_TEST_SUITE(TestCommissioningWindowManager)
