/*
 * Copyright 2020 The Android Open Source Project
 *
 * 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 <fcntl.h>
#include <fuzzer/FuzzedDataProvider.h>
#include "osi/include/alarm.h"
#include "osi/include/semaphore.h"

#include "common/message_loop_thread.h"

using base::Closure;
using base::TimeDelta;
using bluetooth::common::MessageLoopThread;

#define MAX_CONCURRENT_ALARMS 25
#define MAX_BUFFER_LEN 4096
#define MAX_ALARM_DURATION 25

static semaphore_t* semaphore;
static int cb_counter;
static MessageLoopThread* thread = new MessageLoopThread("fake main thread");

bluetooth::common::MessageLoopThread* get_main_thread() { return thread; }

static void cb(void* data) {
  ++cb_counter;
  semaphore_post(semaphore);
}

void setup() {
  cb_counter = 0;
  semaphore = semaphore_new(0);
}
void teardown() { semaphore_free(semaphore); }

alarm_t* fuzz_init_alarm(FuzzedDataProvider* dataProvider) {
  size_t name_len =
      dataProvider->ConsumeIntegralInRange<size_t>(0, MAX_BUFFER_LEN);
  std::vector<char> alarm_name_vect =
      dataProvider->ConsumeBytesWithTerminator<char>(name_len, '\0');
  char* alarm_name = alarm_name_vect.data();

  // Determine if our alarm will be periodic
  if (dataProvider->ConsumeBool()) {
    return alarm_new_periodic(alarm_name);
  } else {
    return alarm_new(alarm_name);
  }
}

bool fuzz_set_alarm(alarm_t* alarm, uint64_t interval, alarm_callback_t cb,
                    FuzzedDataProvider* dataProvider) {
  // Generate a random buffer (or null)
  void* data_buffer = nullptr;
  size_t buff_len =
      dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_LEN);
  if (buff_len == 0) {
    return false;
  }

  // allocate our space
  std::vector<uint8_t> data_vector =
      dataProvider->ConsumeBytes<uint8_t>(buff_len);
  data_buffer = data_vector.data();

  // Make sure alarm is non-null
  if (alarm) {
    // Should this alarm be regular or on mloop?
    if (dataProvider->ConsumeBool()) {
      alarm_set_on_mloop(alarm, interval, cb, data_buffer);
    } else {
      alarm_set(alarm, interval, cb, data_buffer);
    }
  }

  return true;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  // Init our wrapper
  FuzzedDataProvider dataProvider(Data, Size);

  // Perform setup
  setup();

  alarm_t* alarm = nullptr;
  // Should our alarm be valid or null?
  if (dataProvider.ConsumeBool()) {
    // Init our alarm
    alarm = fuzz_init_alarm(&dataProvider);
  }

  // Set up the alarm & cancel
  // Alarm must be non-null, or set() will trigger assert
  if (alarm) {
    if (!fuzz_set_alarm(alarm, MAX_ALARM_DURATION, cb, &dataProvider)) {
      return 0;
    }
    alarm_cancel(alarm);
  }

  // Check if scheduled
  alarm_is_scheduled(alarm);

  if (alarm) {
    // Set up another set of alarms & let these ones run
    int num_alarms =
        dataProvider.ConsumeIntegralInRange<uint8_t>(0, MAX_CONCURRENT_ALARMS);
    for (int i = 0; i < num_alarms; i++) {
      uint64_t interval =
          dataProvider.ConsumeIntegralInRange<uint64_t>(0, MAX_ALARM_DURATION);
      if (fuzz_set_alarm(alarm, interval, cb, &dataProvider)) {
        return 0;
      }
      alarm_get_remaining_ms(alarm);
    }

    // Wait for them to complete
    for (int i = 1; i <= num_alarms; i++) {
      semaphore_wait(semaphore);
    }
  }

  // Free the alarm object
  alarm_free(alarm);

  // dump debug data to /dev/null
  int debug_fd = open("/dev/null", O_RDWR);
  alarm_debug_dump(debug_fd);

  // Cleanup
  alarm_cleanup();

  // Perform teardown
  teardown();

  return 0;
}
