/*
 *
 *    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::kIPv6).SetListenPort(CHIP_PORT)
#if INET_CONFIG_ENABLE_IPV4
                          ,
                      UdpListenParameters(&inetLayer).SetAddressType(Inet::IPAddressType::kIPv4).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)
