// 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 "media/midi/midi_message_util.h"
#include "media/midi/usb_midi_device.h"

namespace media {

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

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

  std::vector<uint8> data_to_send;
  size_t current = 0;
  size_t size = GetSize(data);
  while (current < size) {
    uint8 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>& data) const {
  return data.size() + pending_size_;
}

uint8_t UsbMidiOutputStream::Get(const std::vector<uint8>& 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>& data,
                                           size_t* current,
                                           std::vector<uint8>* data_to_send) {
  size_t index = *current;
  size_t message_size = 0;
  const size_t kMessageSizeMax = 3;
  uint8 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 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 code_index = static_cast<uint8>(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>& data,
    size_t* current,
    std::vector<uint8>* data_to_send) {
  size_t index = *current;
  uint8 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 code_index = message_size == 1 ? 0x5 : static_cast<uint8>(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>& data,
                                           size_t* current,
                                           std::vector<uint8>* data_to_send) {
  size_t index = *current;
  uint8 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>& data,
                                           size_t* current,
                                           std::vector<uint8>* data_to_send) {
  size_t index = *current;
  uint8 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 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 media
