/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/webmidi/MIDIOutput.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/UseCounter.h"
#include "core/timing/DOMWindowPerformance.h"
#include "core/timing/WindowPerformance.h"
#include "core/timing/WorkerGlobalScopePerformance.h"
#include "core/workers/WorkerGlobalScope.h"
#include "media/midi/midi_service.mojom-blink.h"
#include "modules/webmidi/MIDIAccess.h"

using midi::mojom::PortState;

namespace blink {

namespace {

DOMUint8Array* ConvertUnsignedDataToUint8Array(
    Vector<unsigned> unsigned_data,
    ExceptionState& exception_state) {
  DOMUint8Array* array = DOMUint8Array::Create(unsigned_data.size());
  DOMUint8Array::ValueType* array_data = array->Data();
  for (size_t i = 0; i < unsigned_data.size(); ++i) {
    if (unsigned_data[i] > 0xff) {
      exception_state.ThrowTypeError("The value at index " + String::Number(i) +
                                     " (" + String::Number(unsigned_data[i]) +
                                     ") is greater than 0xFF.");
      return nullptr;
    }
    array_data[i] = unsigned_data[i];
  }
  return array;
}

base::TimeTicks GetTimeOrigin(ExecutionContext* context) {
  DCHECK(context);
  Performance* performance = nullptr;
  if (LocalDOMWindow* window = context->ExecutingWindow()) {
    performance = DOMWindowPerformance::performance(*window);
  } else {
    DCHECK(context->IsWorkerGlobalScope());
    performance = WorkerGlobalScopePerformance::performance(
        *static_cast<WorkerGlobalScope*>(context));
  }

  DCHECK(performance);
  return base::TimeTicks() +
         TimeDelta::FromMillisecondsD(performance->timeOrigin());
}

class MessageValidator {
 public:
  static bool Validate(DOMUint8Array* array,
                       ExceptionState& exception_state,
                       bool sysex_enabled) {
    MessageValidator validator(array);
    return validator.Process(exception_state, sysex_enabled);
  }

 private:
  MessageValidator(DOMUint8Array* array)
      : data_(array->Data()), length_(array->length()), offset_(0) {}

  bool Process(ExceptionState& exception_state, bool sysex_enabled) {
    while (!IsEndOfData() && AcceptRealTimeMessages()) {
      if (!IsStatusByte()) {
        exception_state.ThrowTypeError("Running status is not allowed " +
                                       GetPositionString());
        return false;
      }
      if (IsEndOfSysex()) {
        exception_state.ThrowTypeError(
            "Unexpected end of system exclusive message " +
            GetPositionString());
        return false;
      }
      if (IsReservedStatusByte()) {
        exception_state.ThrowTypeError("Reserved status is not allowed " +
                                       GetPositionString());
        return false;
      }
      if (IsSysex()) {
        if (!sysex_enabled) {
          exception_state.ThrowDOMException(
              kInvalidAccessError,
              "System exclusive message is not allowed " + GetPositionString());
          return false;
        }
        if (!AcceptCurrentSysex()) {
          if (IsEndOfData())
            exception_state.ThrowTypeError(
                "System exclusive message is not ended by end of system "
                "exclusive message.");
          else
            exception_state.ThrowTypeError(
                "System exclusive message contains a status byte " +
                GetPositionString());
          return false;
        }
      } else {
        if (!AcceptCurrentMessage()) {
          if (IsEndOfData())
            exception_state.ThrowTypeError("Message is incomplete.");
          else
            exception_state.ThrowTypeError("Unexpected status byte " +
                                           GetPositionString());
          return false;
        }
      }
    }
    return true;
  }

 private:
  bool IsEndOfData() { return offset_ >= length_; }
  bool IsSysex() { return data_[offset_] == 0xf0; }
  bool IsSystemMessage() { return data_[offset_] >= 0xf0; }
  bool IsEndOfSysex() { return data_[offset_] == 0xf7; }
  bool IsRealTimeMessage() { return data_[offset_] >= 0xf8; }
  bool IsStatusByte() { return data_[offset_] & 0x80; }
  bool IsReservedStatusByte() {
    return data_[offset_] == 0xf4 || data_[offset_] == 0xf5 ||
           data_[offset_] == 0xf9 || data_[offset_] == 0xfd;
  }

  bool AcceptRealTimeMessages() {
    for (; !IsEndOfData(); offset_++) {
      if (IsRealTimeMessage() && !IsReservedStatusByte())
        continue;
      return true;
    }
    return false;
  }

  bool AcceptCurrentSysex() {
    DCHECK(IsSysex());
    for (offset_++; !IsEndOfData(); offset_++) {
      if (IsReservedStatusByte())
        return false;
      if (IsRealTimeMessage())
        continue;
      if (IsEndOfSysex()) {
        offset_++;
        return true;
      }
      if (IsStatusByte())
        return false;
    }
    return false;
  }

  bool AcceptCurrentMessage() {
    DCHECK(IsStatusByte());
    DCHECK(!IsSysex());
    DCHECK(!IsReservedStatusByte());
    DCHECK(!IsRealTimeMessage());
    DCHECK(!IsEndOfSysex());
    static const int kChannelMessageLength[7] = {
        3, 3, 3, 3, 2, 2, 3};  // for 0x8*, 0x9*, ..., 0xe*
    static const int kSystemMessageLength[7] = {
        2, 3, 2, 0, 0, 1, 0};  // for 0xf1, 0xf2, ..., 0xf7
    size_t length = IsSystemMessage()
                        ? kSystemMessageLength[data_[offset_] - 0xf1]
                        : kChannelMessageLength[(data_[offset_] >> 4) - 8];
    offset_++;
    DCHECK_GT(length, 0UL);
    if (length == 1)
      return true;
    for (size_t count = 1; !IsEndOfData(); offset_++) {
      if (IsReservedStatusByte())
        return false;
      if (IsRealTimeMessage())
        continue;
      if (IsStatusByte())
        return false;
      if (++count == length) {
        offset_++;
        return true;
      }
    }
    return false;
  }

  String GetPositionString() {
    return "at index " + String::Number(offset_) + " (" +
           String::Number(data_[offset_]) + ").";
  }

  const unsigned char* data_;
  const size_t length_;
  size_t offset_;
};

}  // namespace

MIDIOutput* MIDIOutput::Create(MIDIAccess* access,
                               unsigned port_index,
                               const String& id,
                               const String& manufacturer,
                               const String& name,
                               const String& version,
                               PortState state) {
  DCHECK(access);
  return new MIDIOutput(access, port_index, id, manufacturer, name, version,
                        state);
}

MIDIOutput::MIDIOutput(MIDIAccess* access,
                       unsigned port_index,
                       const String& id,
                       const String& manufacturer,
                       const String& name,
                       const String& version,
                       PortState state)
    : MIDIPort(access, id, manufacturer, name, kTypeOutput, version, state),
      port_index_(port_index) {}

MIDIOutput::~MIDIOutput() = default;

void MIDIOutput::send(NotShared<DOMUint8Array> array,
                      double timestamp_in_milliseconds,
                      ExceptionState& exception_state) {
  ExecutionContext* context = GetExecutionContext();
  if (!context)
    return;

  base::TimeTicks timestamp;
  if (timestamp_in_milliseconds == 0.0) {
    timestamp = base::TimeTicks::Now();
  } else {
    timestamp = GetTimeOrigin(context) +
                base::TimeDelta::FromMillisecondsD(timestamp_in_milliseconds);
  }
  SendInternal(array.View(), timestamp, exception_state);
}

void MIDIOutput::send(Vector<unsigned> unsigned_data,
                      double timestamp_in_milliseconds,
                      ExceptionState& exception_state) {
  if (!GetExecutionContext())
    return;

  DOMUint8Array* array = ConvertUnsignedDataToUint8Array(
      std::move(unsigned_data), exception_state);
  if (!array) {
    DCHECK(exception_state.HadException());
    return;
  }

  send(NotShared<DOMUint8Array>(array), timestamp_in_milliseconds,
       exception_state);
}

void MIDIOutput::send(NotShared<DOMUint8Array> data,
                      ExceptionState& exception_state) {
  if (!GetExecutionContext())
    return;

  DCHECK(data);
  SendInternal(data.View(), base::TimeTicks::Now(), exception_state);
}

void MIDIOutput::send(Vector<unsigned> unsigned_data,
                      ExceptionState& exception_state) {
  if (!GetExecutionContext())
    return;

  DOMUint8Array* array = ConvertUnsignedDataToUint8Array(
      std::move(unsigned_data), exception_state);
  if (!array) {
    DCHECK(exception_state.HadException());
    return;
  }

  SendInternal(array, base::TimeTicks::Now(), exception_state);
}

void MIDIOutput::DidOpen(bool opened) {
  if (!opened) {
    pending_data_.clear();
    return;
  }

  while (!pending_data_.empty()) {
    auto& front = pending_data_.front();
    midiAccess()->SendMIDIData(port_index_, front.first->Data(),
                               front.first->length(), front.second);
    pending_data_.TakeFirst();
  }
}

void MIDIOutput::Trace(blink::Visitor* visitor) {
  MIDIPort::Trace(visitor);
  visitor->Trace(pending_data_);
}

void MIDIOutput::SendInternal(DOMUint8Array* array,
                              base::TimeTicks timestamp,
                              ExceptionState& exception_state) {
  DCHECK(GetExecutionContext());
  DCHECK(array);
  DCHECK(!timestamp.is_null());
  UseCounter::Count(GetExecutionContext(), WebFeature::kMIDIOutputSend);

  // Implicit open. It does nothing if the port is already opened.
  // This should be performed even if |array| is invalid.
  open();

  if (!MessageValidator::Validate(array, exception_state,
                                  midiAccess()->sysexEnabled()))
    return;

  if (IsOpening()) {
    pending_data_.emplace_back(array, timestamp);
  } else {
    midiAccess()->SendMIDIData(port_index_, array->Data(), array->length(),
                               timestamp);
  }
}

}  // namespace blink
