/*
 *
 *    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.
 */

#if CONFIG_NETWORK_LAYER_BLE
#include <ble/BleLayer.h>
#endif // CONFIG_NETWORK_LAYER_BLE
#include <controller/CHIPDevice.h>
#include <inet/IPAddress.h>
#include <inet/InetLayer.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/SessionIDAllocator.h>
#include <system/SystemLayerImpl.h>
#include <transport/SessionManager.h>
#include <transport/TransportMgr.h>
#include <transport/raw/PeerAddress.h>
#include <transport/raw/UDP.h>

using namespace chip;
using namespace chip::Transport;
using namespace chip::Controller;
using namespace chip::Messaging;

namespace {

using TestTransportMgr = TransportMgr<Transport::UDP>;

void TestDevice_EstablishSessionDirectly(nlTestSuite * inSuite, void * inContext)
{
    Platform::MemoryInit();
    DeviceTransportMgr transportMgr;
    SessionManager sessionManager;
    ExchangeManager exchangeMgr;
    Inet::InetLayer inetLayer;
    System::LayerImpl systemLayer;
#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer blelayer;
#endif // CONFIG_NETWORK_LAYER_BLE
    // Heap-allocate the fairly large FabricTable so we don't end up with a huge
    // stack.
    FabricTable * fabrics = Platform::New<FabricTable>();
    secure_channel::MessageCounterManager messageCounterManager;
    SessionIDAllocator idAllocator;

    systemLayer.Init();
    inetLayer.Init(systemLayer, nullptr);
    transportMgr.Init(
        UdpListenParameters(&inetLayer).SetAddressType(Inet::IPAddressType::kIPAddressType_IPv6).SetListenPort(CHIP_PORT)
#if INET_CONFIG_ENABLE_IPV4
            ,
        UdpListenParameters(&inetLayer).SetAddressType(Inet::kIPAddressType_IPv4).SetListenPort(CHIP_PORT)
#endif
#if CONFIG_NETWORK_LAYER_BLE
            ,
        BleListenParameters(&blelayer)
#endif
    );
    sessionManager.Init(&systemLayer, &transportMgr, &messageCounterManager);
    exchangeMgr.Init(&sessionManager);
    messageCounterManager.Init(&exchangeMgr);

    ControllerDeviceInitParams params = {
        .transportMgr    = &transportMgr,
        .sessionManager  = &sessionManager,
        .exchangeMgr     = &exchangeMgr,
        .inetLayer       = &inetLayer,
        .storageDelegate = nullptr,
        .idAllocator     = &idAllocator,
        .fabricsTable    = fabrics,
    };
    Device device;
    NodeId mockNodeId           = 1;
    FabricIndex mockFabricIndex = 1;
    Inet::IPAddress mockAddr;
    Inet::IPAddress::FromString("::1", mockAddr);
    PeerAddress addr = PeerAddress::UDP(mockAddr, CHIP_PORT);
    device.Init(params, mockNodeId, addr, mockFabricIndex);

    device.OperationalCertProvisioned();
    NL_TEST_ASSERT(inSuite, device.EstablishConnectivity(nullptr, nullptr) == CHIP_NO_ERROR);

    device.Reset();
    messageCounterManager.Shutdown();
    exchangeMgr.Shutdown();
    sessionManager.Shutdown();
    Platform::Delete(fabrics);
    transportMgr.Close();
    inetLayer.Shutdown();
    systemLayer.Shutdown();
    Platform::MemoryShutdown();
}

// clang-format off
const nlTest sTests[] =
{
    NL_TEST_DEF("TestDevice_EstablishSessionDirectly", TestDevice_EstablishSessionDirectly),
    NL_TEST_SENTINEL()
};
// clang-format on

} // namespace

int TestDevice()
{
    nlTestSuite theSuite = { "Device", &sTests[0], NULL, NULL };
    nlTestRunner(&theSuite, nullptr);
    return nlTestRunnerStats(&theSuite);
}

CHIP_REGISTER_TEST_SUITE(TestDevice)
