// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/sched/run-queue.h>
#include <lib/sched/thread-base.h>
#include <zircon/time.h>

#include <memory>
#include <vector>

#include <fuzzer/FuzzedDataProvider.h>

#include "test-thread.h"

//
// This file defines a simple fuzzer of sched::RunQueue, simulating the ongoing
// scheduling of threads.
//

namespace {

using Duration = sched::Duration;
using FlexibleWeight = sched::FlexibleWeight;
using Time = sched::Time;

Time ConsumeTime(FuzzedDataProvider& provider) {
  return Time{provider.ConsumeIntegral<zx_time_t>()};
}

FlexibleWeight ConsumeFlexibleWeight(FuzzedDataProvider& provider, FlexibleWeight min) {
  return FlexibleWeight{
      provider.ConsumeIntegralInRange<int64_t>(min.raw_value(), FlexibleWeight::Max().raw_value())};
}

Duration ConsumeDuration(FuzzedDataProvider& provider, Duration min, Duration max) {
  ZX_ASSERT(min >= 0);
  ZX_ASSERT(max >= min);
  return Duration{provider.ConsumeIntegralInRange<zx_duration_t>(min.raw_value(), max.raw_value())};
}

TestThread* AllocateNewThread(FuzzedDataProvider& provider,
                              std::vector<std::unique_ptr<TestThread>>& threads) {
  Time start = ConsumeTime(provider);
  Duration period = ConsumeDuration(provider, Duration{1}, (Time::Max() - start) + Time{1});
  Duration firm_capacity = ConsumeDuration(provider, Duration{0}, period);
  FlexibleWeight flexible_weight =
      ConsumeFlexibleWeight(provider, FlexibleWeight{firm_capacity == 0 ? 1 : 0});
  threads.emplace_back(std::make_unique<TestThread>(
      sched::BandwidthParameters{
          .period = period,
          .firm_capacity = firm_capacity,
          .flexible_weight = flexible_weight,
      },
      start));
  return threads.back().get();
}

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  FuzzedDataProvider provider(data, size);

  std::vector<std::unique_ptr<TestThread>> threads;
  Time now = ConsumeTime(provider);
  TestThread* current = nullptr;
  sched::RunQueue<TestThread> queue;
  while (now < Time::Max() && provider.remaining_bytes() > 0) {
    if (provider.ConsumeBool()) {
      queue.Queue(*AllocateNewThread(provider, threads), now);
    }

    ZX_ASSERT(current == queue.current_thread());
    if (current) {
      ZX_ASSERT(!current->IsQueued());
      ZX_ASSERT(current->start() <= now);
    }

    auto [next, preemption] = queue.SelectNextThread(now);

    ZX_ASSERT(current == next || !current || current->IsQueued());

    if (next) {
      ZX_ASSERT(!next->IsQueued());
      ZX_ASSERT(next->start() <= now);
      ZX_ASSERT(now < preemption);
      ZX_ASSERT(preemption <= next->finish());

      next->Tick(preemption - now);
    }

    now = preemption;
    current = next;
  }

  return 0;
}
