/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 *
 * 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.
 *
 * This file is part of the TinyUSB stack.
 */

#include "tusb_option.h"

#if CFG_TUH_ENABLED || CFG_TUD_ENABLED

#include "tusb.h"
#include "common/tusb_private.h"

#if CFG_TUD_ENABLED
#include "device/usbd_pvt.h"
#endif

#if CFG_TUH_ENABLED
#include "host/usbh_pvt.h"
#endif

//--------------------------------------------------------------------+
// Public API
//--------------------------------------------------------------------+

bool tusb_init(void)
{
#if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT)
  // init device stack CFG_TUSB_RHPORTx_MODE must be defined
  TU_ASSERT ( tud_init(TUD_OPT_RHPORT) );
#endif

#if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT)
  // init host stack CFG_TUSB_RHPORTx_MODE must be defined
  TU_ASSERT( tuh_init(TUH_OPT_RHPORT) );
#endif

  return true;
}

bool tusb_inited(void)
{
  bool ret = false;

#if CFG_TUD_ENABLED
  ret = ret || tud_inited();
#endif

#if CFG_TUH_ENABLED
  ret = ret || tuh_inited();
#endif

  return ret;
}

//--------------------------------------------------------------------+
// Descriptor helper
//--------------------------------------------------------------------+

uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1)
{
  while(desc+1 < end)
  {
    if ( desc[1] == byte1 ) return desc;
    desc += desc[DESC_OFFSET_LEN];
  }
  return NULL;
}

uint8_t const * tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2)
{
  while(desc+2 < end)
  {
    if ( desc[1] == byte1 && desc[2] == byte2) return desc;
    desc += desc[DESC_OFFSET_LEN];
  }
  return NULL;
}

uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3)
{
  while(desc+3 < end)
  {
    if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc;
    desc += desc[DESC_OFFSET_LEN];
  }
  return NULL;
}


//--------------------------------------------------------------------+
// Endpoint Helper for both Host and Device stack
//--------------------------------------------------------------------+

bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
{
  (void) mutex;

  // pre-check to help reducing mutex lock
  TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0));
  (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);

  // can only claim the endpoint if it is not busy and not claimed yet.
  bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0);
  if (available)
  {
    ep_state->claimed = 1;
  }

  (void) osal_mutex_unlock(mutex);

  return available;
}

bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
{
  (void) mutex;

  (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);

  // can only release the endpoint if it is claimed and not busy
  bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0);
  if (ret)
  {
    ep_state->claimed = 0;
  }

  (void) osal_mutex_unlock(mutex);

  return ret;
}

bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed)
{
  uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep);
  TU_LOG2("  Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);

  switch (desc_ep->bmAttributes.xfer)
  {
    case TUSB_XFER_ISOCHRONOUS:
    {
      uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023);
      TU_ASSERT(max_packet_size <= spec_size);
    }
    break;

    case TUSB_XFER_BULK:
      if (speed == TUSB_SPEED_HIGH)
      {
        // Bulk highspeed must be EXACTLY 512
        TU_ASSERT(max_packet_size == 512);
      }else
      {
        // TODO Bulk fullspeed can only be 8, 16, 32, 64
        TU_ASSERT(max_packet_size <= 64);
      }
    break;

    case TUSB_XFER_INTERRUPT:
    {
      uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
      TU_ASSERT(max_packet_size <= spec_size);
    }
    break;

    default: return false;
  }

  return true;
}

void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id)
{
  uint8_t const* p_desc = (uint8_t const*) desc_itf;
  uint8_t const* desc_end = p_desc + desc_len;

  while( p_desc < desc_end )
  {
    if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
    {
      uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;

      TU_LOG(2, "  Bind EP %02x to driver id %u\r\n", ep_addr, driver_id);
      ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
    }

    p_desc = tu_desc_next(p_desc);
  }
}

uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len)
{
  uint8_t const* p_desc = (uint8_t const*) desc_itf;
  uint16_t len = 0;

  while (itf_count--)
  {
    // Next on interface desc
    len += tu_desc_len(desc_itf);
    p_desc = tu_desc_next(p_desc);

    while (len < max_len)
    {
      // return on IAD regardless of itf count
      if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len;

      if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
           ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 )
      {
        break;
      }

      len += tu_desc_len(p_desc);
      p_desc = tu_desc_next(p_desc);
    }
  }

  return len;
}

//--------------------------------------------------------------------+
// Endpoint Stream Helper for both Host and Device stack
//--------------------------------------------------------------------+

bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
                         void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize)
{
  osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex);
  (void) new_mutex;
  (void) is_tx;

  s->is_host = is_host;
  tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
  tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex);

  s->ep_buf = ep_buf;
  s->ep_bufsize = ep_bufsize;

  return true;
}

TU_ATTR_ALWAYS_INLINE static inline
bool stream_claim(tu_edpt_stream_t* s)
{
  if (s->is_host)
  {
    #if CFG_TUH_ENABLED
    return usbh_edpt_claim(s->daddr, s->ep_addr);
    #endif
  }else
  {
    #if CFG_TUD_ENABLED
    return usbd_edpt_claim(s->rhport, s->ep_addr);
    #endif
  }

  return false;
}

TU_ATTR_ALWAYS_INLINE static inline
bool stream_xfer(tu_edpt_stream_t* s, uint16_t count)
{
  if (s->is_host)
  {
    #if CFG_TUH_ENABLED
    return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count);
    #endif
  }else
  {
    #if CFG_TUD_ENABLED
    return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count);
    #endif
  }

  return false;
}

TU_ATTR_ALWAYS_INLINE static inline
bool stream_release(tu_edpt_stream_t* s)
{
  if (s->is_host)
  {
    #if CFG_TUH_ENABLED
    return usbh_edpt_release(s->daddr, s->ep_addr);
    #endif
  }else
  {
    #if CFG_TUD_ENABLED
    return usbd_edpt_release(s->rhport, s->ep_addr);
    #endif
  }

  return false;
}

//--------------------------------------------------------------------+
// Stream Write
//--------------------------------------------------------------------+

bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes)
{
  // ZLP condition: no pending data, last transferred bytes is multiple of packet size
  TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize-1))) );

  TU_VERIFY( stream_claim(s) );
  TU_ASSERT( stream_xfer(s, 0) );

  return true;
}

uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s)
{
  // skip if no data
  TU_VERIFY( tu_fifo_count(&s->ff), 0 );

  // Claim the endpoint
  TU_VERIFY( stream_claim(s), 0 );

  // Pull data from FIFO -> EP buf
  uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);

  if ( count )
  {
    TU_ASSERT( stream_xfer(s, count), 0 );
    return count;
  }else
  {
    // Release endpoint since we don't make any transfer
    // Note: data is dropped if terminal is not connected
    stream_release(s);
    return 0;
  }
}

uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize)
{
  TU_VERIFY(bufsize); // TODO support ZLP

  uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);

  // flush if fifo has more than packet size or
  // in rare case: fifo depth is configured too small (which never reach packet size)
  if ( (tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize) )
  {
    tu_edpt_stream_write_xfer(s);
  }

  return ret;
}

//--------------------------------------------------------------------+
// Stream Read
//--------------------------------------------------------------------+

uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s)
{
  uint16_t available = tu_fifo_remaining(&s->ff);

  // Prepare for incoming data but only allow what we can store in the ring buffer.
  // TODO Actually we can still carry out the transfer, keeping count of received bytes
  // and slowly move it to the FIFO when read().
  // This pre-check reduces endpoint claiming
  TU_VERIFY(available >= s->ep_packetsize);

  // claim endpoint
  TU_VERIFY(stream_claim(s), 0);

  // get available again since fifo can be changed before endpoint is claimed
  available = tu_fifo_remaining(&s->ff);

  if ( available >= s->ep_packetsize )
  {
    // multiple of packet size limit by ep bufsize
    uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1));
    count = tu_min16(count, s->ep_bufsize);

    TU_ASSERT( stream_xfer(s, count), 0 );

    return count;
  }else
  {
    // Release endpoint since we don't make any transfer
    stream_release(s);
    return 0;
  }
}

uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize)
{
  uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize);
  tu_edpt_stream_read_xfer(s);
  return num_read;
}

//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+

#if CFG_TUSB_DEBUG
#include <ctype.h>

#if CFG_TUSB_DEBUG >= 2

char const* const tu_str_speed[] = { "Full", "Low", "High" };
char const* const tu_str_std_request[] =
{
  "Get Status"        ,
  "Clear Feature"     ,
  "Reserved"          ,
  "Set Feature"       ,
  "Reserved"          ,
  "Set Address"       ,
  "Get Descriptor"    ,
  "Set Descriptor"    ,
  "Get Configuration" ,
  "Set Configuration" ,
  "Get Interface"     ,
  "Set Interface"     ,
  "Synch Frame"
};

char const* const tu_str_xfer_result[] = {
    "OK", "FAILED", "STALLED", "TIMEOUT"
};

#endif

static void dump_str_line(uint8_t const* buf, uint16_t count)
{
  tu_printf("  |");

  // each line is 16 bytes
  for(uint16_t i=0; i<count; i++)
  {
    const char ch = buf[i];
    tu_printf("%c", isprint(ch) ? ch : '.');
  }

  tu_printf("|\r\n");
}

/* Print out memory contents
 *  - buf   : buffer
 *  - count : number of item
 *  - indent: prefix spaces on every line
 */
void tu_print_mem(void const *buf, uint32_t count, uint8_t indent)
{
  uint8_t const size = 1; // fixed 1 byte for now

  if ( !buf || !count )
  {
    tu_printf("NULL\r\n");
    return;
  }

  uint8_t const *buf8 = (uint8_t const *) buf;

  char format[] = "%00X";
  format[2] += 2*size;

  const uint8_t item_per_line  = 16 / size;

  for(unsigned int i=0; i<count; i++)
  {
    unsigned int value=0;

    if ( i%item_per_line == 0 )
    {
      // Print Ascii
      if ( i != 0 )
      {
        dump_str_line(buf8-16, 16);
      }

      for(uint8_t s=0; s < indent; s++) tu_printf(" ");

      // print offset or absolute address
      tu_printf("%04X: ", 16*i/item_per_line);
    }

    tu_memcpy_s(&value, sizeof(value), buf8, size);
    buf8 += size;

    tu_printf(" ");
    tu_printf(format, value);
  }

  // fill up last row to 16 for printing ascii
  const uint32_t remain = count%16;
  uint8_t nback = (uint8_t)(remain ? remain : 16);

  if ( remain )
  {
    for(uint32_t i=0; i< 16-remain; i++)
    {
      tu_printf(" ");
      for(int j=0; j<2*size; j++) tu_printf(" ");
    }
  }

  dump_str_line(buf8-nback, nback);
}

#endif

#endif // host or device enabled
