// Copyright 2019 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/fuchsia/cdm/fuchsia_stream_decryptor.h"

#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/media/drm/cpp/fidl.h>

#include "base/bind.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h"
#include "media/base/subsample_entry.h"

namespace media {
namespace {


std::string GetEncryptionScheme(EncryptionScheme mode) {
  switch (mode) {
    case EncryptionScheme::kCenc:
      return fuchsia::media::ENCRYPTION_SCHEME_CENC;
    case EncryptionScheme::kCbcs:
      return fuchsia::media::ENCRYPTION_SCHEME_CBCS;
    default:
      NOTREACHED() << "unknown encryption mode " << static_cast<int>(mode);
      return "";
  }
}

std::vector<fuchsia::media::SubsampleEntry> GetSubsamples(
    const std::vector<SubsampleEntry>& subsamples) {
  std::vector<fuchsia::media::SubsampleEntry> fuchsia_subsamples(
      subsamples.size());

  for (size_t i = 0; i < subsamples.size(); i++) {
    fuchsia_subsamples[i].clear_bytes = subsamples[i].clear_bytes;
    fuchsia_subsamples[i].encrypted_bytes = subsamples[i].cypher_bytes;
  }

  return fuchsia_subsamples;
}

fuchsia::media::EncryptionPattern GetEncryptionPattern(
    EncryptionPattern pattern) {
  fuchsia::media::EncryptionPattern fuchsia_pattern;
  fuchsia_pattern.clear_blocks = pattern.skip_byte_block();
  fuchsia_pattern.encrypted_blocks = pattern.crypt_byte_block();
  return fuchsia_pattern;
}

fuchsia::media::FormatDetails GetClearFormatDetails() {
  fuchsia::media::EncryptedFormat encrypted_format;
  encrypted_format.set_scheme(fuchsia::media::ENCRYPTION_SCHEME_UNENCRYPTED)
      .set_subsamples({})
      .set_init_vector({});

  fuchsia::media::FormatDetails format;
  format.set_format_details_version_ordinal(0);
  format.mutable_domain()->crypto().set_encrypted(std::move(encrypted_format));
  return format;
}

fuchsia::media::FormatDetails GetEncryptedFormatDetails(
    const DecryptConfig* config) {
  DCHECK(config);

  fuchsia::media::EncryptedFormat encrypted_format;
  encrypted_format.set_scheme(GetEncryptionScheme(config->encryption_scheme()))
      .set_key_id(std::vector<uint8_t>(config->key_id().begin(),
                                       config->key_id().end()))
      .set_init_vector(
          std::vector<uint8_t>(config->iv().begin(), config->iv().end()))
      .set_subsamples(GetSubsamples(config->subsamples()));
  if (config->encryption_scheme() == EncryptionScheme::kCbcs) {
    DCHECK(config->encryption_pattern().has_value());
    encrypted_format.set_pattern(
        GetEncryptionPattern(config->encryption_pattern().value()));
  }

  fuchsia::media::FormatDetails format;
  format.set_format_details_version_ordinal(0);
  format.mutable_domain()->crypto().set_encrypted(std::move(encrypted_format));
  return format;
}

}  // namespace

FuchsiaStreamDecryptor::FuchsiaStreamDecryptor(
    fuchsia::media::StreamProcessorPtr processor)
    : processor_(std::move(processor), this),
      allocator_("CrFuchsiaStreamDecryptor") {}

FuchsiaStreamDecryptor::~FuchsiaStreamDecryptor() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

base::RepeatingClosure FuchsiaStreamDecryptor::GetOnNewKeyClosure() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return BindToCurrentLoop(base::BindRepeating(
      &FuchsiaStreamDecryptor::OnNewKey, weak_factory_.GetWeakPtr()));
}

void FuchsiaStreamDecryptor::Initialize(Sink* sink,
                                        size_t min_buffer_size,
                                        size_t min_buffer_count) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  sink_ = sink;

  min_buffer_size_ = min_buffer_size;
  min_buffer_count_ = min_buffer_count;

  input_buffer_collection_ = allocator_.AllocateNewCollection();
  input_buffer_collection_->CreateSharedToken(
      base::BindOnce(&StreamProcessorHelper::SetInputBufferCollectionToken,
                     base::Unretained(&processor_)));
  auto buffer_constraints = VmoBuffer::GetRecommendedConstraints(
      kInputBufferCount, min_buffer_size_, /*writable=*/true);
  input_buffer_collection_->Initialize(std::move(buffer_constraints),
                                       "CrFuchsiaStreamDecryptor");
  input_buffer_collection_->AcquireBuffers(base::BindOnce(
      &FuchsiaStreamDecryptor::OnInputBuffersAcquired, base::Unretained(this)));
}

void FuchsiaStreamDecryptor::EnqueueBuffer(
    scoped_refptr<DecoderBuffer> buffer) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  input_writer_queue_.EnqueueBuffer(std::move(buffer));
}

void FuchsiaStreamDecryptor::Reset() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Close current stream and drop all the cached decoder buffers.
  // Keep input and output buffers to avoid buffer re-allocation.
  processor_.Reset();
  input_writer_queue_.ResetQueue();
  waiting_for_key_ = false;
}

void FuchsiaStreamDecryptor::OnStreamProcessorAllocateOutputBuffers(
    const fuchsia::media::StreamBufferConstraints& stream_constraints) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  output_buffer_collection_ = allocator_.AllocateNewCollection();
  output_buffer_collection_->CreateSharedToken(
      base::BindOnce(&StreamProcessorHelper::CompleteOutputBuffersAllocation,
                     base::Unretained(&processor_)));
  output_buffer_collection_->CreateSharedToken(
      base::BindOnce(&Sink::OnSysmemBufferStreamBufferCollectionToken,
                     base::Unretained(sink_)));

  fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;
  buffer_constraints.usage.none = fuchsia::sysmem::noneUsage;
  buffer_constraints.min_buffer_count = min_buffer_count_;
  buffer_constraints.has_buffer_memory_constraints = true;
  buffer_constraints.buffer_memory_constraints.min_size_bytes =
      min_buffer_size_;
  buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
  buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
  buffer_constraints.buffer_memory_constraints.inaccessible_domain_supported =
      true;

  output_buffer_collection_->Initialize(std::move(buffer_constraints),
                                        "CrFuchsiaStreamDecryptorOutput");
}

void FuchsiaStreamDecryptor::OnStreamProcessorEndOfStream() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  sink_->OnSysmemBufferStreamEndOfStream();
}

void FuchsiaStreamDecryptor::OnStreamProcessorOutputFormat(
    fuchsia::media::StreamOutputFormat format) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void FuchsiaStreamDecryptor::OnStreamProcessorOutputPacket(
    StreamProcessorHelper::IoPacket packet) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  sink_->OnSysmemBufferStreamOutputPacket(std::move(packet));
}

void FuchsiaStreamDecryptor::OnStreamProcessorNoKey() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!waiting_for_key_);

  // Reset stream position, but keep all pending buffers. They will be
  // resubmitted later, when we have a new key.
  input_writer_queue_.ResetPositionAndPause();

  if (retry_on_no_key_event_) {
    retry_on_no_key_event_ = false;
    input_writer_queue_.Unpause();
    return;
  }

  waiting_for_key_ = true;
  sink_->OnSysmemBufferStreamNoKey();
}

void FuchsiaStreamDecryptor::OnStreamProcessorError() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  OnError();
}

void FuchsiaStreamDecryptor::OnError() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  Reset();

  // No need to reset other fields since OnError() is called for non-recoverable
  // errors.

  sink_->OnSysmemBufferStreamError();
}

void FuchsiaStreamDecryptor::OnInputBuffersAcquired(
    std::vector<VmoBuffer> buffers,
    const fuchsia::sysmem::SingleBufferSettings&) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (buffers.empty()) {
    OnError();
    return;
  }

  input_writer_queue_.Start(
      std::move(buffers),
      base::BindRepeating(&FuchsiaStreamDecryptor::SendInputPacket,
                          base::Unretained(this)),
      base::BindRepeating(&FuchsiaStreamDecryptor::ProcessEndOfStream,
                          base::Unretained(this)));
}

void FuchsiaStreamDecryptor::SendInputPacket(
    const DecoderBuffer* buffer,
    StreamProcessorHelper::IoPacket packet) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!packet.unit_end()) {
    // The encrypted data size is too big. Decryptor should consider
    // splitting the buffer and update the IV and subsample entries.
    // TODO(crbug.com/1003651): Handle large encrypted buffer correctly. For
    // now, just reject the decryption.
    LOG(ERROR) << "DecoderBuffer doesn't fit in one packet.";
    OnError();
    return;
  }

  fuchsia::media::FormatDetails format =
      (buffer->decrypt_config())
          ? GetEncryptedFormatDetails(buffer->decrypt_config())
          : GetClearFormatDetails();

  packet.set_format(std::move(format));
  processor_.Process(std::move(packet));
}

void FuchsiaStreamDecryptor::ProcessEndOfStream() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  processor_.ProcessEos();
}

void FuchsiaStreamDecryptor::OnNewKey() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!waiting_for_key_) {
    retry_on_no_key_event_ = true;
    return;
  }

  DCHECK(!retry_on_no_key_event_);
  waiting_for_key_ = false;
  input_writer_queue_.Unpause();
}

}  // namespace media
