/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2022 Nathaniel Brough
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */
#include "device/dcd.h"
#include "fuzz/fuzz_private.h"
#include <assert.h>
#include <cstdint>
#include <limits>

#define UNUSED(x) (void)(x)

//--------------------------------------------------------------------+
// State tracker
//--------------------------------------------------------------------+
struct State {
  bool interrupts_enabled;
  bool sof_enabled;
  uint8_t address;
};

tu_static State state = {false, 0, 0};

//--------------------------------------------------------------------+
// Controller API
// All no-ops as we are fuzzing.
//--------------------------------------------------------------------+
extern "C" {
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
  UNUSED(rhport);
  UNUSED(rh_init);
  return true;
}

void dcd_int_handler(uint8_t rhport) {
  assert(_fuzz_data_provider.has_value());

  if (!state.interrupts_enabled) {
    return;
  }

  // Choose if we want to generate a signal based on the fuzzed data.
  if (_fuzz_data_provider->ConsumeBool()) {
    // Only generate bus signal events that don't carry additional union data.
    // DCD_EVENT_XFER_COMPLETE, DCD_EVENT_SOF, and DCD_EVENT_BUS_RESET need
    // properly initialized union fields; USBD_EVENT_FUNC_CALL is internal only.
    // Valid bus-signal-only events: UNPLUGGED(2), SUSPEND(4), RESUME(5).
    static const dcd_eventid_t bus_signal_events[] = {
        DCD_EVENT_UNPLUGGED, DCD_EVENT_SUSPEND, DCD_EVENT_RESUME};
    uint8_t idx = _fuzz_data_provider->ConsumeIntegralInRange<uint8_t>(0, 2);
    dcd_event_bus_signal(rhport, bus_signal_events[idx],
                         _fuzz_data_provider->ConsumeBool());
  }

  // Optionally generate a BUS_RESET event with a valid speed value.
  if (_fuzz_data_provider->ConsumeBool()) {
    tusb_speed_t speed = (tusb_speed_t)_fuzz_data_provider->ConsumeIntegralInRange<uint8_t>(
        TUSB_SPEED_FULL, TUSB_SPEED_HIGH);
    dcd_event_bus_reset(rhport, speed, _fuzz_data_provider->ConsumeBool());
  }

  if (_fuzz_data_provider->ConsumeBool()) {
    constexpr size_t kSetupFrameLength = 8;
    std::vector<uint8_t> setup =
        _fuzz_data_provider->ConsumeBytes<uint8_t>(kSetupFrameLength);
    // Fuzz consumer may return less than requested. If this is the case
    // we want to make sure that at least that length is allocated and available
    // to the signal handler.
    if (setup.size() != kSetupFrameLength) {
      setup.resize(kSetupFrameLength);
    }
    dcd_event_setup_received(rhport, setup.data(),
                             // Identify trigger as either an interrupt or a
                             // syncrhonous call depending on fuzz data.
                             _fuzz_data_provider->ConsumeBool());
  }
}

void dcd_int_enable(uint8_t rhport) {
  state.interrupts_enabled = true;
  UNUSED(rhport);
  return;
}

void dcd_int_disable(uint8_t rhport) {
  state.interrupts_enabled = false;
  UNUSED(rhport);
  return;
}

void dcd_set_address(uint8_t rhport, uint8_t dev_addr) {
  UNUSED(rhport);
  state.address = dev_addr;
  // Respond with status.
  dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false);
  return;
}

void dcd_remote_wakeup(uint8_t rhport) {
  UNUSED(rhport);
  return;
}

void dcd_connect(uint8_t rhport) {
  UNUSED(rhport);
  return;
}

void dcd_disconnect(uint8_t rhport) {
  UNUSED(rhport);
  return;
}

void dcd_sof_enable(uint8_t rhport, bool en) {
  state.sof_enabled = en;
  UNUSED(rhport);
  return;
}

//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+

// Configure endpoint's registers according to descriptor
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
  UNUSED(rhport);
  UNUSED(desc_ep);
  return _fuzz_data_provider->ConsumeBool();
}

// Close all non-control endpoints, cancel all pending transfers if any.
// Invoked when switching from a non-zero Configuration by SET_CONFIGURE
// therefore required for multiple configuration support.
void dcd_edpt_close_all(uint8_t rhport) {
  UNUSED(rhport);
  return;
}

// Close an endpoint.
// Since it is weak, caller must TU_ASSERT this function's existence before
// calling it.
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
  UNUSED(rhport);
  UNUSED(ep_addr);
  return;
}

// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to
// notify the stack
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer,
                   uint16_t total_bytes, bool is_isr) {
  UNUSED(rhport);
  UNUSED(buffer);
  UNUSED(total_bytes);
  UNUSED(is_isr);

  uint8_t const dir = tu_edpt_dir(ep_addr);

  if (dir == TUSB_DIR_IN) {
    std::vector<uint8_t> temp =
        _fuzz_data_provider->ConsumeBytes<uint8_t>(total_bytes);
    std::copy(temp.begin(), temp.end(), buffer);
  }
  // Ignore output data as it's not useful for fuzzing without a more
  // complex fuzzed backend. But we need to make sure it's not
  // optimised out.
  volatile uint8_t *dont_optimise0 = buffer;
  volatile uint16_t dont_optimise1 = total_bytes;
  UNUSED(dont_optimise0);
  UNUSED(dont_optimise1);


  return _fuzz_data_provider->ConsumeBool();
}

/* TODO: implement a fuzzed version of this.
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff,
                        uint16_t total_bytes) {}
*/

// Stall endpoint, any queuing transfer should be removed from endpoint
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {

  UNUSED(rhport);
  UNUSED(ep_addr);
  return;
}

// clear stall, data toggle is also reset to DATA0
// This API never calls with control endpoints, since it is auto cleared when
// receiving setup packet
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {

  UNUSED(rhport);
  UNUSED(ep_addr);
  return;
}
}
