// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"

#include <utility>

#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame_metadata.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/webrtc/api/frame_transformer_interface.h"

namespace blink {
namespace {

struct SetMetadataValidationOutcome {
  bool allowed;
  String error_msg;
};

SetMetadataValidationOutcome IsAllowedSetMetadataChange(
    const RTCEncodedAudioFrameMetadata* current_metadata,
    const RTCEncodedAudioFrameMetadata* new_metadata) {
  // Only changing the RTP Timestamp is supported.

  if (new_metadata->hasSynchronizationSource() !=
          current_metadata->hasSynchronizationSource() ||
      (new_metadata->hasSynchronizationSource() &&
       current_metadata->synchronizationSource() !=
           new_metadata->synchronizationSource())) {
    return SetMetadataValidationOutcome{false, "Bad synchronizationSource"};
  }
  if (new_metadata->hasContributingSources() !=
          current_metadata->hasContributingSources() ||
      (new_metadata->hasContributingSources() &&
       current_metadata->contributingSources() !=
           new_metadata->contributingSources())) {
    return SetMetadataValidationOutcome{false, "Bad contributingSources"};
  }
  if (new_metadata->hasPayloadType() != current_metadata->hasPayloadType() ||
      (new_metadata->hasPayloadType() &&
       current_metadata->payloadType() != new_metadata->payloadType())) {
    return SetMetadataValidationOutcome{false, "Bad payloadType"};
  }
  if (new_metadata->hasSequenceNumber() !=
          current_metadata->hasSequenceNumber() ||
      (new_metadata->hasSequenceNumber() &&
       current_metadata->sequenceNumber() != new_metadata->sequenceNumber())) {
    return SetMetadataValidationOutcome{false, "Bad sequenceNumber"};
  }
  if (new_metadata->hasAbsCaptureTime() !=
          current_metadata->hasAbsCaptureTime() ||
      (new_metadata->hasAbsCaptureTime() &&
       current_metadata->absCaptureTime() != new_metadata->absCaptureTime())) {
    return SetMetadataValidationOutcome{false, "Bad absoluteCaptureTime"};
  }
  if (!new_metadata->hasRtpTimestamp()) {
    return SetMetadataValidationOutcome{false, "Bad rtpTimestamp"};
  }
  return SetMetadataValidationOutcome{true, String()};
}

}  // namespace

RTCEncodedAudioFrame* RTCEncodedAudioFrame::Create(
    RTCEncodedAudioFrame* original_frame,
    ExceptionState& exception_state) {
  return RTCEncodedAudioFrame::Create(original_frame, nullptr, exception_state);
}

RTCEncodedAudioFrame* RTCEncodedAudioFrame::Create(
    RTCEncodedAudioFrame* original_frame,
    RTCEncodedAudioFrameMetadata* new_metadata,
    ExceptionState& exception_state) {
  RTCEncodedAudioFrame* new_frame;
  if (original_frame) {
    new_frame = MakeGarbageCollected<RTCEncodedAudioFrame>(
        original_frame->Delegate()->CloneWebRtcFrame());
  } else {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidAccessError,
        "Cannot create a new AudioFrame: input Audioframe is empty.");
    return nullptr;
  }
  if (new_metadata) {
    base::expected<void, String> set_metadata =
        new_frame->SetMetadata(new_metadata);
    if (!set_metadata.has_value()) {
      exception_state.ThrowDOMException(
          DOMExceptionCode::kInvalidModificationError,
          "Cannot create a new AudioFrame: " + set_metadata.error());
      return nullptr;
    }
  }
  return new_frame;
}

RTCEncodedAudioFrame::RTCEncodedAudioFrame(
    std::unique_ptr<webrtc::TransformableAudioFrameInterface>
        webrtc_audio_frame)
    : delegate_(base::MakeRefCounted<RTCEncodedAudioFrameDelegate>(
          std::move(webrtc_audio_frame),
          webrtc_audio_frame ? webrtc_audio_frame->GetContributingSources()
                             : Vector<uint32_t>(),
          webrtc_audio_frame ? webrtc_audio_frame->SequenceNumber()
                             : std::nullopt)) {}

RTCEncodedAudioFrame::RTCEncodedAudioFrame(
    scoped_refptr<RTCEncodedAudioFrameDelegate> delegate)
    : RTCEncodedAudioFrame(delegate->CloneWebRtcFrame()) {}

uint32_t RTCEncodedAudioFrame::timestamp() const {
  return delegate_->RtpTimestamp();
}

DOMArrayBuffer* RTCEncodedAudioFrame::data() const {
  if (!frame_data_) {
    frame_data_ = delegate_->CreateDataBuffer();
  }
  return frame_data_.Get();
}

RTCEncodedAudioFrameMetadata* RTCEncodedAudioFrame::getMetadata() const {
  RTCEncodedAudioFrameMetadata* metadata =
      RTCEncodedAudioFrameMetadata::Create();
  if (delegate_->Ssrc()) {
    metadata->setSynchronizationSource(*delegate_->Ssrc());
  }
  metadata->setContributingSources(delegate_->ContributingSources());
  if (delegate_->PayloadType()) {
    metadata->setPayloadType(*delegate_->PayloadType());
  }
  if (delegate_->SequenceNumber()) {
    metadata->setSequenceNumber(*delegate_->SequenceNumber());
  }
  if (delegate_->AbsCaptureTime()) {
    metadata->setAbsCaptureTime(*delegate_->AbsCaptureTime());
  }
  metadata->setRtpTimestamp(delegate_->RtpTimestamp());
  if (delegate_->MimeType()) {
    metadata->setMimeType(WTF::String::FromUTF8(*delegate_->MimeType()));
  }
  return metadata;
}

base::expected<void, String> RTCEncodedAudioFrame::SetMetadata(
    const RTCEncodedAudioFrameMetadata* metadata) {
  SetMetadataValidationOutcome validation =
      IsAllowedSetMetadataChange(getMetadata(), metadata);
  if (!validation.allowed) {
    return base::unexpected(
        "Invalid modification of RTCEncodedAudioFrameMetadata. " +
        validation.error_msg);
  }

  return delegate_->SetRtpTimestamp(metadata->rtpTimestamp());
}

void RTCEncodedAudioFrame::setMetadata(RTCEncodedAudioFrameMetadata* metadata,
                                       ExceptionState& exception_state) {
  base::expected<void, String> set_metadata = SetMetadata(metadata);
  if (!set_metadata.has_value()) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidModificationError,
        "Cannot setMetadata: " + set_metadata.error());
  }
}

void RTCEncodedAudioFrame::setData(DOMArrayBuffer* data) {
  frame_data_ = data;
}

String RTCEncodedAudioFrame::toString() const {
  StringBuilder sb;
  sb.Append("RTCEncodedAudioFrame{rtpTimestamp: ");
  sb.AppendNumber(delegate_->RtpTimestamp());
  sb.Append(", size: ");
  sb.AppendNumber(data() ? data()->ByteLength() : 0);
  sb.Append("}");
  return sb.ToString();
}

void RTCEncodedAudioFrame::SyncDelegate() const {
  delegate_->SetData(frame_data_);
}

scoped_refptr<RTCEncodedAudioFrameDelegate> RTCEncodedAudioFrame::Delegate()
    const {
  SyncDelegate();
  return delegate_;
}

std::unique_ptr<webrtc::TransformableAudioFrameInterface>
RTCEncodedAudioFrame::PassWebRtcFrame() {
  SyncDelegate();
  return delegate_->PassWebRtcFrame();
}

void RTCEncodedAudioFrame::Trace(Visitor* visitor) const {
  ScriptWrappable::Trace(visitor);
  visitor->Trace(frame_data_);
}

}  // namespace blink
