// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include "usb_utils.h"
#include "usbdpi.h"

// Seed numbers for the LFSR generators in each transfer direction for
// the given stream number
#define USBTST_LFSR_SEED(s) (uint8_t)(0x10U + (s)*7U)
#define USBDPI_LFSR_SEED(s) (uint8_t)(0x9BU - (s)*7U)
// Seed number of packet retrying
#define RETRY_LFSR_SEED(s) (uint8_t)(0x24U + (s)*7U)

// Simple LFSR for 8-bit sequences
#define LFSR_ADVANCE(lfsr) \
  (((lfsr) << 1) ^         \
   ((((lfsr) >> 1) ^ ((lfsr) >> 2) ^ ((lfsr) >> 3) ^ ((lfsr) >> 7)) & 1u))

// Stream signature words
#define STREAM_SIGNATURE_HEAD 0x579EA01AU
#define STREAM_SIGNATURE_TAIL 0x160AE975U

// Verbose logging/diagnostic reporting
// TODO - consider folding this into the existing log level
static const bool verbose = false;

static const bool expect_sig = true;

// Determine the next stream for which IN data packets shall be requested
static inline unsigned in_stream_next(usbdpi_ctx_t *ctx);

// Determine the next stream for which OUT data shall be sent
static inline unsigned out_stream_next(usbdpi_ctx_t *ctx);

// Check a data packet received from the test software (usbdev_stream_test)
static bool stream_data_check(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                              const usbdpi_transfer_t *rx, bool accept);

// Generate a data packet as if it had been received from the device
static usbdpi_transfer_t *stream_data_gen(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                                          unsigned len);

// Check a data packet received from the test software (usbdev_stream_test)
// and collect the data, combined with our LFSR-generated random stream,
// for later transmission back to the device
static usbdpi_transfer_t *stream_data_process(usbdpi_ctx_t *ctx,
                                              usbdpi_stream_t *s,
                                              usbdpi_transfer_t *rx);

// Check the stream signature
static bool stream_sig_check(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                             usbdpi_transfer_t *rx);

// Determine the next stream for which IN data packets shall be requested
inline unsigned in_stream_next(usbdpi_ctx_t *ctx) {
  uint8_t id = ctx->stream_in;
  if (++id >= ctx->nstreams) {
    id = 0U;
  }
  ctx->stream_in = id;
  return id;
}

// Determine the next stream for which OUT data shall be sent
inline unsigned out_stream_next(usbdpi_ctx_t *ctx) {
  uint8_t id = ctx->stream_out;
  if (++id >= ctx->nstreams) {
    id = 0U;
  }
  ctx->stream_out = id;
  return id;
}

// Initialize streaming state for the given number of streams
bool streams_init(usbdpi_ctx_t *ctx, unsigned nstreams, bool retrieve,
                  bool checking, bool retrying, bool send) {
  assert(ctx);

  // Can we support the requested number of streams?
  if (!nstreams || nstreams > USBDPI_MAX_STREAMS) {
    return false;
  }

  if (verbose) {
    printf("[usbdpi] Stream test running with %u streams(s)\n", nstreams);
    printf("[usbdpi] - retrieve %c checking %c retrying %c send %c\n",
           retrieve ? 'Y' : 'N', checking ? 'Y' : 'N', retrying ? 'Y' : 'N',
           send ? 'Y' : 'N');
  }

  // Remember the number of streams and initialize the arbitration of
  // IN and OUT traffic
  ctx->nstreams = nstreams;
  ctx->stream_in = 0U;
  ctx->stream_out = nstreams - 1U;

  for (unsigned id = 0U; id < nstreams; id++) {
    // Poll device for IN packets in streaming test?
    ctx->stream[id].retrieve = retrieve;
    // Attempt to sent OUT packets to device in streaming test?
    ctx->stream[id].send = send;
    // Checking of received data against expected LFSR output
    ctx->stream[id].checking = checking;
    // Request retrying of IN packets, feigning error
    ctx->stream[id].retrying = retrying;
    // Endpoints to be used by this stream
    ctx->stream[id].ep_in = 1U + id;
    ctx->stream[id].ep_out = 1U + id;
    // LFSR state for this byte stream
    ctx->stream[id].tst_lfsr = USBTST_LFSR_SEED(id);
    ctx->stream[id].dpi_lfsr = USBDPI_LFSR_SEED(id);
    // LFSR-controlled packet retrying state
    ctx->stream[id].retry_lfsr = RETRY_LFSR_SEED(id);
    ctx->stream[id].nretries = 0U;
    // No received packets
    ctx->stream[id].received = NULL;
  }
  return true;
}

// Check a data packet received from the test software (usbdev_stream_test)
bool stream_data_check(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                       const usbdpi_transfer_t *rx, bool accept) {
  assert(rx);

  // The byte count _includes_ the DATAx PID and the two CRC bytes
  //
  // Note: we are expecting a LFSR-generated byte stream, but we do not
  //       make assumptions about the number or size of the data packets
  //       that make up the stream

  unsigned num_bytes = transfer_length(rx);
  unsigned idx = rx->data_start + 1u;  // Skip past the DATAx PID
  bool ok = false;

  // Validate the received packet - data length valid and checksum present
  if (num_bytes >= sizeof(rx->data) || idx + 2u > num_bytes) {
    printf("[usbdpi] Unexpected/malformed data packet (0x%x 0x%x)\n", idx,
           num_bytes);
  } else {
    // Data field within received packet
    const uint8_t *sp = &rx->data[idx];
    num_bytes -= 3u;

    // Check that the CRC16 checksum of the data field is as expected
    uint16_t rx_crc = sp[num_bytes] | (sp[num_bytes + 1u] << 8);
    uint16_t crc = CRC16(sp, num_bytes);
    if (rx_crc != crc) {
      printf("[usbdpi] Mismatched CRC16 0x%04x received, expected 0x%04x\n",
             rx_crc, crc);
    } else {
      // Data toggle synchronization
      unsigned pid = ctx->ep_in[s->ep_in].next_data;
      if (rx->data[0] == pid) {
        // If we've decided to reject this packet then we still check its
        // content but we do not advance the data toggle because we're
        // pretending that we didn't receive it successfully
        if (accept) {
          ctx->ep_in[s->ep_in].next_data = DATA_TOGGLE_ADVANCE(pid);
        }

        // Tentatively acceptable, but we still have to check and report any and
        // all mismatched bytes
        ok = accept;
      }

      // Iff running a performance investigation, checking may be undesired
      // because it causes us to reject and retry the transmission
      if (s->checking) {
        // Note: use a local copy of the LFSR so that we can check the data
        //       field even on those packets that we choose to reject
        uint8_t tst_lfsr = s->tst_lfsr;
        while (num_bytes-- > 0U) {
          uint8_t recvd = *sp++;
          if (recvd != tst_lfsr) {
            printf(
                "[usbdpi] Mismatched data from device 0x%02x, "
                "expected 0x%02x\n",
                recvd, tst_lfsr);
            ok = false;
          }
          // Advance our local LFSR
          tst_lfsr = LFSR_ADVANCE(tst_lfsr);
        }

        // Update the LFSR only if we've accepted valid data and will not
        // be receiving this data again
        if (accept && ok) {
          s->tst_lfsr = tst_lfsr;
        }
      } else {
        printf("[usbdpi] Warning: Stream data checking disabled\n");
      }
    }
  }

  return ok;
}

// Generate a data packet as if it had been received from the device
usbdpi_transfer_t *stream_data_gen(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                                   unsigned len) {
  usbdpi_transfer_t *tr = transfer_alloc(ctx);
  if (tr) {
    // Pretend that we have successfully received the packet with the correct
    // data toggling...
    uint8_t data = ctx->ep_in[s->ep_in].next_data;
    ctx->ep_in[s->ep_in].next_data = DATA_TOGGLE_ADVANCE(data);
    // ...and that the data is as expected
    uint8_t *dp = transfer_data_start(tr, data, len);
    for (unsigned idx = 0U; idx < len; idx++) {
      dp[idx] = s->tst_lfsr;
      s->tst_lfsr = LFSR_ADVANCE(s->tst_lfsr);
    }
    transfer_data_end(tr, dp + len);
  }
  return tr;
}

// Process a received data packet to produce a corresponding reply packet
// by XORing our LFSR output with the received data
//
// Note: for now we do this even if the received data mismatches because
//       only the CPU software has the capacity to decide upon and report
//       test status
usbdpi_transfer_t *stream_data_process(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                                       usbdpi_transfer_t *rx) {
  // Note: checkStreamData has already been called on this packet
  assert(rx);

  // The byte count _includes_ the DATAx PID and the two CRC bytes
  unsigned num_bytes = rx->num_bytes;
  unsigned idx = rx->data_start + 1u;  // Skip past the DATAx PID

  // Data field within received packet
  const uint8_t *sp = &rx->data[idx];
  num_bytes -= 3u;

  // Allocate a new buffer for the reply
  usbdpi_transfer_t *reply = transfer_alloc(ctx);
  assert(reply);

  // Construct OUT token packet to the target endpoint, using the
  // appropriate DATAx PID
  const uint8_t ep_out = s->ep_out;
  transfer_token(reply, USB_PID_OUT, ctx->dev_address, ep_out);
  uint8_t *dp =
      transfer_data_start(reply, ctx->ep_out[ep_out].next_data, num_bytes);
  assert(dp);

  while (num_bytes-- > 0U) {
    uint8_t recvd = *sp++;

    // Simply XOR the two LFSR-generated streams together
    *dp++ = recvd ^ s->dpi_lfsr;
    if (verbose) {
      printf("[usbdpi] 0x%02x <- 0x%02x ^ 0x%02x\n", *(dp - 1), recvd,
             s->dpi_lfsr);
    }

    // Advance our LFSR
    //
    // TODO - decide whether we want to do this here; if the device
    // responds with a NAK, requiring us to retry, or we decide to
    // resend the packet, then we don't want to advance again
    s->dpi_lfsr = LFSR_ADVANCE(s->dpi_lfsr);
  }

  transfer_data_end(reply, dp);

  return reply;
}

// Check the stream signature
bool stream_sig_check(usbdpi_ctx_t *ctx, usbdpi_stream_t *s,
                      usbdpi_transfer_t *rx) {
  // Packet should be PID, data field and CRC16
  if (transfer_length(rx) == 3U + 0x10U) {
    const uint8_t *sig = transfer_data_field(rx);
    if (sig) {
      // Signature format:
      //   Bits Description
      //   32   head signature
      //   8    initial vaue of LFSR
      //   8    stream number
      //   16   reserved, SBZ
      //   32   number of bytes to be transferred
      //   32   tail signature
      // Note: all 32-bit quantities are in little endian order

      uint32_t num_bytes = get_le32(&sig[8]);
      if (verbose) {
        printf("[usbdpi] Stream signature at %p head 0x%x tail 0x%x\n", sig,
               get_le32(&sig[0]), get_le32(&sig[12]));
      }

      // Basic validation check; words are transmitted in little endian order
      if (get_le32(&sig[0]) == STREAM_SIGNATURE_HEAD &&
          get_le32(&sig[12]) == STREAM_SIGNATURE_TAIL &&
          // sanity check on transfer length, though we rely upon the CPU
          // software to send, receive and count the number of bytes
          num_bytes > 0U && num_bytes < 0x10000000U && !sig[6] && !sig[7]) {
        // Signature includes the initial value of the device-side LFSR
        s->tst_lfsr = sig[4];
        // Update data toggle
        uint8_t pid = transfer_data_pid(rx);
        ctx->ep_in[s->ep_in].next_data = DATA_TOGGLE_ADVANCE(pid);
        return true;
      }
    }
  }
  return false;
}

// Service streaming data (usbdev_stream_test)
void streams_service(usbdpi_ctx_t *ctx) {
  if (verbose) {
    //    printf("[usbdpi] streams_service hostSt %u in %u out %u\n",
    //    ctx->hostSt,
    //           ctx->stream_in, ctx->stream_out);
  }

  // Maximum time for transmission of a packet ought to be circa 80 bytes of
  // data, 640 bits. Allowing for bitstuffing this means we need to leave ~800
  const unsigned min_time_left = 800U;

  switch (ctx->hostSt) {
    // --------------------------------------------
    // Try to transmit a data packet to the device
    // --------------------------------------------
    case HS_STARTFRAME:
    case HS_STREAMOUT: {
      // Decide whether we have enough time within this frame to attempt
      // another transmission
      uint32_t next_frame = ctx->frame_start + FRAME_INTERVAL;
      if ((next_frame - ctx->tick_bits) > min_time_left) {  // HACK
        unsigned id = out_stream_next(ctx);
        usbdpi_stream_t *s = &ctx->stream[id];
        if (s->send) {
          // Start by trying to transmit a data packet that we've received, if
          // any
          if (s->received) {
            if (ctx->sending) {
              transfer_release(ctx, ctx->sending);
            }

            // Scramble the oldest received packet with our LFSR-generated byte
            // stream and send it to the device
            usbdpi_transfer_t *reply = stream_data_process(ctx, s, s->received);
            transfer_send(ctx, reply);

            uint32_t max_bits =
                transfer_length(ctx->sending) * 10 + 160;  // HACK
            ctx->wait = USBDPI_TIMEOUT(ctx, max_bits);
            ctx->bus_state = kUsbBulkOut;
            ctx->lastrxpid = 0;
            ctx->hostSt = HS_WAITACK;
          } else {
            // Nothing to send, try receiving...
            ctx->hostSt = HS_STREAMIN;
          }
        } else {
          // We're not sending anything - discard any received data
          while (s->received) {
            usbdpi_transfer_t *tr = s->received;
            s->received = tr->next;
            transfer_release(ctx, tr);
          }
          ctx->hostSt = HS_STREAMIN;
        }
      } else {
        // Wait until the next bus frame
        ctx->hostSt = HS_NEXTFRAME;
      }
    } break;

    // Await acknowledgement of the packet that we just transmitted
    case HS_WAITACK:
      if (ctx->sending) {
        // Forget reference to the buffer we just tried to send; the received
        // packet remains in the list of received buffers to try again later
        transfer_release(ctx, ctx->sending);
        ctx->sending = NULL;
      }

      if (ctx->bus_state == kUsbBulkOutAck) {
        bool proceed = false;

        if (verbose) {
          printf("[usbdpi] OUT - response is PID 0x%02x from device (%s)\n",
                 ctx->lastrxpid, decode_pid(ctx->lastrxpid));
        }

        switch (ctx->lastrxpid) {
          case USB_PID_ACK: {
            // Transmitted packet was accepted, so we can retire it...
            usbdpi_stream_t *s = &ctx->stream[ctx->stream_out];
            usbdpi_transfer_t *rx = s->received;
            assert(rx);
            s->received = rx->next;
            transfer_release(ctx, rx);

            uint8_t ep_out = s->ep_out;
            ctx->ep_out[ep_out].next_data =
                DATA_TOGGLE_ADVANCE(ctx->ep_out[ep_out].next_data);
            proceed = true;
          } break;

          // We may receive a NAK from the device if it is unable to receive the
          // packet right now
          case USB_PID_NAK:
            printf(
                "[usbdpi] frame 0x%x tick_bits 0x%x NAK received from device\n",
                ctx->frame, ctx->tick_bits);
            proceed = true;
            break;

          default:
            printf("[usbdpi] Unexpected PID 0x%02x from device (%s)\n",
                   ctx->lastrxpid, decode_pid(ctx->lastrxpid));
            ctx->hostSt = HS_NEXTFRAME;
            break;
        }

        ctx->hostSt = proceed ? HS_STREAMIN : HS_NEXTFRAME;
      } else if (ctx->tick_bits >= ctx->wait) {
        printf("[usbdpi] Timed out waiting for OUT response\n");
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;

    // ---------------------------------------------
    // Try to collect a data packet from the device
    // ---------------------------------------------
    case HS_STREAMIN: {
      // Decide whether we have enough time within this frame to attempt
      // another fetch
      //
      // TODO - find out what the host behaviour should be at this point;
      //        the device must be required to respond within a certain
      //        time interval, and then the bus transmission speed
      //        determines the maximum delay
      uint32_t next_frame = ctx->frame_start + FRAME_INTERVAL;
      if ((next_frame - ctx->tick_bits) > min_time_left) {  // HACK
        unsigned id = in_stream_next(ctx);
        usbdpi_stream_t *s = &ctx->stream[id];
        if (s->retrieve) {
          // Ensure that a buffer is available for constructing a transfer
          usbdpi_transfer_t *tr = ctx->sending;
          if (!tr) {
            tr = transfer_alloc(ctx);
            assert(tr);

            ctx->sending = tr;
          }

          transfer_token(tr, USB_PID_IN, ctx->dev_address, s->ep_in);

          transfer_send(ctx, tr);
          ctx->bus_state = kUsbBulkInToken;
          ctx->hostSt = HS_WAIT_PKT;
          ctx->lastrxpid = 0;
        } else {
          // We're not required to poll for IN data, but if we're sending we
          //   must still fake the reception of valid packet data because
          //   the sw test will be expecting valid data
          if (s->send && !s->received) {
            // For simplicity we just create max length packets
            const unsigned len = USBDEV_MAX_PACKET_SIZE;
            s->received = stream_data_gen(ctx, s, len);
          }
          ctx->hostSt = HS_STREAMOUT;
        }
      } else {
        // Wait until the next bus frame
        ctx->hostSt = HS_NEXTFRAME;
      }
    } break;

    case HS_WAIT_PKT:
      // Wait max time for a response + packet
      ctx->wait = ctx->tick_bits + 18 + 8 + 8 + 64 * 8 + 16;
      ctx->hostSt = HS_ACKIFDATA;
      break;
    case HS_ACKIFDATA:
      if (ctx->bus_state == kUsbBulkInData && ctx->recving) {
        // We have a response from the device
        switch (ctx->lastrxpid) {
          case USB_PID_DATA0:
          case USB_PID_DATA1: {
            // Steal the received packet; it belongs to the stream
            usbdpi_transfer_t *rx = ctx->recving;
            ctx->recving = NULL;
            // Decide whether we want to ACK or NAK this packet
            unsigned id = ctx->stream_in;
            usbdpi_stream_t *s = &ctx->stream[id];
            bool accept = false;
            if (s->retrying && s->nretries) {
              s->nretries--;
            } else {
              // Decide the number of retries for the next data packet
              // Note: by randomizing the number of retries, rather than
              // independently deciding each accept/reject, we guarantee an
              // upper bound on the run time
              switch (s->retry_lfsr & 7U) {
                case 7U:
                  s->nretries = 3U;
                  break;
                case 6U:
                case 5U:
                  s->nretries = 2U;
                  break;
                case 4U:
                  s->nretries = 1U;
                  break;
                default:
                  s->nretries = 0U;
                  break;
              }
              s->retry_lfsr = LFSR_ADVANCE(s->retry_lfsr);
              accept = true;
            }
            if (!accept) {
              printf("[usbdpi] Requesting resend of data\n");
              usb_monitor_log(ctx->mon, "[usbdpi] Requesting resend of data\n");
            }

            if (expect_sig && !s->sig_recvd) {
              // Note: the stream signature is primarily of use on a physical
              // USB connection to a host since the endpoint to port mapping is
              // variable. With t-l sim we can rely upon the first packet being
              // the signature and nothing else
              accept = stream_sig_check(ctx, s, rx);
              transfer_release(ctx, rx);
              // TODO - run time error, signal test failure to the software
              assert(accept);
              if (accept) {
                s->sig_recvd = true;
              }
            } else {
              if (stream_data_check(ctx, s, rx, accept)) {
                // Collect the received packets in preparation for later
                // transmission with modification back to the device
                usbdpi_transfer_t *tr = s->received;
                if (tr) {
                  while (tr->next)
                    tr = tr->next;
                  tr->next = rx;
                } else {
                  s->received = rx;
                }
              } else {
                transfer_release(ctx, rx);
                accept = false;
              }
            }

            usbdpi_transfer_t *tr = ctx->sending;
            assert(tr);

            transfer_status(ctx, tr, accept ? USB_PID_ACK : USB_PID_NAK);

            ctx->hostSt = HS_STREAMOUT;
          } break;

          case USB_PID_NAK:
            // No data available
            ctx->hostSt = HS_STREAMOUT;
            break;

          default:
            printf("[usbdpi] Unexpected PID 0x%02x from device (%s)\n",
                   ctx->lastrxpid, decode_pid(ctx->lastrxpid));
            ctx->hostSt = HS_NEXTFRAME;
            break;
        }
      } else if (ctx->tick_bits >= ctx->wait) {
        printf("[usbdpi] Timed out waiting for IN response\n");
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;

    default:
      break;
  }
}
