// Copyright 2014 The Chromium 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 "media/midi/usb_midi_output_stream.h"

#include "base/logging.h"
#include "base/macros.h"
#include "media/midi/midi_message_util.h"
#include "media/midi/usb_midi_device.h"

namespace media {
namespace midi {

UsbMidiOutputStream::UsbMidiOutputStream(const UsbMidiJack& jack)
    : jack_(jack), pending_size_(0), is_sending_sysex_(false) {}

void UsbMidiOutputStream::Send(const std::vector<uint8_t>& data) {
  // To prevent link errors caused by DCHECK_*.
  const size_t kPacketContentSize = UsbMidiOutputStream::kPacketContentSize;
  DCHECK_LT(jack_.cable_number, 16u);

  std::vector<uint8_t> data_to_send;
  size_t current = 0;
  size_t size = GetSize(data);
  while (current < size) {
    uint8_t first_byte = Get(data, current);
    if (first_byte == kSysExByte || is_sending_sysex_) {
      // System Exclusive messages
      if (!PushSysExMessage(data, &current, &data_to_send))
        break;
    } else if ((first_byte & kSysMessageBitMask) == kSysMessageBitPattern) {
      if (first_byte & 0x08) {
        // System Real-Time messages
        PushSysRTMessage(data, &current, &data_to_send);
      } else {
        // System Common messages
        if (!PushSysCommonMessage(data, &current, &data_to_send))
          break;
      }
    } else if (first_byte & 0x80) {
      if (!PushChannelMessage(data, &current, &data_to_send))
        break;
    } else {
      // Unknown messages
      DVLOG(1) << "Unknown byte: " << static_cast<unsigned int>(first_byte);
      ++current;
    }
  }

  if (data_to_send.size() > 0)
    jack_.device->Send(jack_.endpoint_number(), data_to_send);

  DCHECK_LE(current, size);
  DCHECK_LE(size - current, kPacketContentSize);
  // Note that this can be a self-copying and the iteration order is important.
  for (size_t i = current; i < size; ++i)
    pending_data_[i - current] = Get(data, i);
  pending_size_ = size - current;
}

size_t UsbMidiOutputStream::GetSize(const std::vector<uint8_t>& data) const {
  return data.size() + pending_size_;
}

uint8_t UsbMidiOutputStream::Get(const std::vector<uint8_t>& data,
                                 size_t index) const {
  DCHECK_LT(index, GetSize(data));
  if (index < pending_size_)
    return pending_data_[index];
  return data[index - pending_size_];
}

bool UsbMidiOutputStream::PushSysExMessage(const std::vector<uint8_t>& data,
                                           size_t* current,
                                           std::vector<uint8_t>* data_to_send) {
  size_t index = *current;
  size_t message_size = 0;
  const size_t kMessageSizeMax = 3;
  uint8_t message[kMessageSizeMax] = {};

  while (index < GetSize(data)) {
    if (message_size == kMessageSizeMax) {
      // We can't find the end-of-message mark in the three bytes.
      *current = index;
      data_to_send->push_back((jack_.cable_number << 4) | 0x4);
      data_to_send->insert(data_to_send->end(),
                           message,
                           message + arraysize(message));
      is_sending_sysex_ = true;
      return true;
    }
    uint8_t byte = Get(data, index);
    if ((byte & kSysRTMessageBitMask) == kSysRTMessageBitPattern) {
      // System Real-Time messages interleaved in a SysEx message
      PushSysRTMessage(data, &index, data_to_send);
      continue;
    }

    message[message_size] = byte;
    ++message_size;
    if (byte == kEndOfSysExByte) {
      uint8_t code_index = static_cast<uint8_t>(message_size) + 0x4;
      DCHECK(code_index == 0x5 || code_index == 0x6 || code_index == 0x7);
      data_to_send->push_back((jack_.cable_number << 4) | code_index);
      data_to_send->insert(data_to_send->end(),
                           message,
                           message + arraysize(message));
      *current = index + 1;
      is_sending_sysex_ = false;
      return true;
    }
    ++index;
  }
  return false;
}

bool UsbMidiOutputStream::PushSysCommonMessage(
    const std::vector<uint8_t>& data,
    size_t* current,
    std::vector<uint8_t>* data_to_send) {
  size_t index = *current;
  uint8_t first_byte = Get(data, index);
  DCHECK_LE(0xf1, first_byte);
  DCHECK_LE(first_byte, 0xf7);
  DCHECK_EQ(0xf0, first_byte & 0xf8);
  // There are only 6 message types (0xf1 - 0xf7), so the table size is 8.
  const size_t message_size_table[8] = {
    0, 2, 3, 2, 1, 1, 1, 0,
  };
  size_t message_size = message_size_table[first_byte & 0x07];
  DCHECK_NE(0u, message_size);
  DCHECK_LE(message_size, 3u);

  if (GetSize(data) < index + message_size) {
    // The message is incomplete.
    return false;
  }

  uint8_t code_index =
      message_size == 1 ? 0x5 : static_cast<uint8_t>(message_size);
  data_to_send->push_back((jack_.cable_number << 4) | code_index);
  for (size_t i = index; i < index + 3; ++i)
    data_to_send->push_back(i < index + message_size ? Get(data, i) : 0);
  *current += message_size;
  return true;
}

void UsbMidiOutputStream::PushSysRTMessage(const std::vector<uint8_t>& data,
                                           size_t* current,
                                           std::vector<uint8_t>* data_to_send) {
  size_t index = *current;
  uint8_t first_byte = Get(data, index);
  DCHECK_LE(0xf8, first_byte);
  DCHECK_LE(first_byte, 0xff);

  data_to_send->push_back((jack_.cable_number << 4) | 0x5);
  data_to_send->push_back(first_byte);
  data_to_send->push_back(0);
  data_to_send->push_back(0);
  *current += 1;
}

bool UsbMidiOutputStream::PushChannelMessage(
    const std::vector<uint8_t>& data,
    size_t* current,
    std::vector<uint8_t>* data_to_send) {
  size_t index = *current;
  uint8_t first_byte = Get(data, index);

  DCHECK_LE(0x80, (first_byte & 0xf0));
  DCHECK_LE((first_byte & 0xf0), 0xe0);
  // There are only 7 message types (0x8-0xe in the higher four bits), so the
  // table size is 8.
  const size_t message_size_table[8] = {
    3, 3, 3, 3, 2, 3, 3, 0,
  };
  uint8_t code_index = first_byte >> 4;
  DCHECK_LE(0x08, code_index);
  DCHECK_LE(code_index, 0x0e);
  size_t message_size = message_size_table[code_index & 0x7];
  DCHECK_NE(0u, message_size);
  DCHECK_LE(message_size, 3u);

  if (GetSize(data) < index + message_size) {
    // The message is incomplete.
    return false;
  }

  data_to_send->push_back((jack_.cable_number << 4) | code_index);
  for (size_t i = index; i < index + 3; ++i)
    data_to_send->push_back(i < index + message_size ? Get(data, i) : 0);
  *current += message_size;
  return true;
}

}  // namespace midi
}  // namespace media
