/*
 *    Copyright (c) 2022 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 "AppMain.h"
#include <app/server/Server.h>

#include <CommissionableInit.h>

using namespace chip;
using namespace chip::DeviceLayer;

namespace {

LinuxCommissionableDataProvider gCommissionableDataProvider;

}

void CleanShutdown()
{
    ApplicationShutdown();
    Server::GetInstance().Shutdown();
    PlatformMgr().Shutdown();
    // TODO: We don't Platform::MemoryShutdown because ~CASESessionManager calls
    // Dnssd::ResolverProxy::Shutdown, which starts doing Platform::Delete.
    // Platform::MemoryShutdown();
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t * aData, size_t aSize)
{
    static bool matterStackInitialized = false;
    if (!matterStackInitialized)
    {
        // Might be simpler to do ChipLinuxAppInit() with argc == 0, argv set to
        // just a fake executable name?
        VerifyOrDie(Platform::MemoryInit() == CHIP_NO_ERROR);
        VerifyOrDie(PlatformMgr().InitChipStack() == CHIP_NO_ERROR);

        VerifyOrDie(chip::examples::InitCommissionableDataProvider(gCommissionableDataProvider,
                                                                   LinuxDeviceOptions::GetInstance()) == CHIP_NO_ERROR);
        SetCommissionableDataProvider(&gCommissionableDataProvider);

        // ChipLinuxAppMainLoop blocks, and we don't want that here.
        static chip::CommonCaseDeviceServerInitParams initParams;
        (void) initParams.InitializeStaticResourcesBeforeServerInit();
        VerifyOrDie(Server::GetInstance().Init(initParams) == CHIP_NO_ERROR);

        ApplicationInit();

        // We don't start the event loop task, because we don't plan to deliver
        // data on a separate thread.

        matterStackInitialized = true;

        // The fuzzer does not have a way to tell us when it's done, so just
        // shut down things on exit.
        atexit(CleanShutdown);
    }

    // For now, just dump the data as a UDP payload into the session manager.
    // But maybe we should try to separately extract a PeerAddress and data from
    // the incoming data?

    // To avoid out-of-bounds access when acessing aData[1]
    if (aSize < 2)
    {
        return 0;
    }

    // dumping payload with fuzzed transport types
    constexpr uint8_t numberOfTypes     = static_cast<int>(Transport::Type::kLast) + 1;
    Transport::Type fuzzedTransportType = static_cast<Transport::Type>(aData[0] % numberOfTypes);
    Transport::PeerAddress peerAddr(fuzzedTransportType);

    System::PacketBufferHandle buf =
        System::PacketBufferHandle::NewWithData(&aData[1], aSize - 1, /* aAdditionalSize = */ 0, /* aReservedSize = */ 0);
    if (buf.IsNull())
    {
        // Too big; we couldn't represent this as a packetbuffer to start with.
        return 0;
    }

    // Ignoring the return value from OnMessageReceived, because we might be
    // passing it all sorts of garbage that will cause it to fail.

    // for TCP we need to have MessageTransportContext
    if (fuzzedTransportType == Transport::Type::kTcp)
    {
        Transport::MessageTransportContext msgContext;
        Server::GetInstance().GetSecureSessionManager().OnMessageReceived(peerAddr, std::move(buf), &msgContext);
    }
    else
    {
        Server::GetInstance().GetSecureSessionManager().OnMessageReceived(peerAddr, std::move(buf));
    }
    // Now process pending events until our sentinel is reached.
    PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().StopEventLoopTask(); });
    PlatformMgr().RunEventLoop();
    return 0;
}
