// Copyright 2021 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/common/decrypting_sysmem_buffer_stream.h"

#include "media/base/callback_registry.h"
#include "media/base/decoder_buffer.h"

namespace media {

DecryptingSysmemBufferStream::DecryptingSysmemBufferStream(
    SysmemAllocatorClient* sysmem_allocator,
    CdmContext* cdm_context,
    Decryptor::StreamType stream_type)
    : passthrough_stream_(sysmem_allocator),
      decryptor_(cdm_context->GetDecryptor()),
      stream_type_(stream_type) {
  DCHECK(decryptor_);

  event_cb_registration_ = cdm_context->RegisterEventCB(
      base::BindRepeating(&DecryptingSysmemBufferStream::OnCdmContextEvent,
                          weak_factory_.GetWeakPtr()));
}

DecryptingSysmemBufferStream::~DecryptingSysmemBufferStream() = default;

void DecryptingSysmemBufferStream::Initialize(Sink* sink,
                                              size_t min_buffer_size,
                                              size_t min_buffer_count) {
  sink_ = sink;
  passthrough_stream_.Initialize(sink, min_buffer_size, min_buffer_count);
}

void DecryptingSysmemBufferStream::EnqueueBuffer(
    scoped_refptr<DecoderBuffer> buffer) {
  buffer_queue_.push_back(std::move(buffer));
  DecryptNextBuffer();
}

void DecryptingSysmemBufferStream::Reset() {
  buffer_queue_.clear();

  if (state_ == State::kDecryptPending) {
    decryptor_->CancelDecrypt(stream_type_);
  }

  state_ = State::kIdle;
  retry_on_no_key_ = false;
}

void DecryptingSysmemBufferStream::OnCdmContextEvent(CdmContext::Event event) {
  if (event != CdmContext::Event::kHasAdditionalUsableKey)
    return;

  switch (state_) {
    case State::kIdle:
      break;

    case State::kDecryptPending:
      retry_on_no_key_ = true;
      break;

    case State::kWaitingKey:
      state_ = State::kIdle;
      DecryptNextBuffer();
      break;
  }
}

void DecryptingSysmemBufferStream::DecryptNextBuffer() {
  if (buffer_queue_.empty() || state_ != State::kIdle)
    return;

  if (buffer_queue_.front()->end_of_stream()) {
    scoped_refptr<DecoderBuffer> buffer = std::move(buffer_queue_.front());
    buffer_queue_.pop_front();
    DCHECK(buffer_queue_.empty());
    passthrough_stream_.EnqueueBuffer(std::move(buffer));
    return;
  }

  state_ = State::kDecryptPending;
  decryptor_->Decrypt(
      stream_type_, buffer_queue_.front(),
      base::BindOnce(&DecryptingSysmemBufferStream::OnBufferDecrypted,
                     weak_factory_.GetWeakPtr()));
}

void DecryptingSysmemBufferStream::OnBufferDecrypted(
    Decryptor::Status status,
    scoped_refptr<DecoderBuffer> decrypted_buffer) {
  DCHECK(state_ == State::kDecryptPending);
  state_ = State::kIdle;

  switch (status) {
    case Decryptor::kError:
      sink_->OnSysmemBufferStreamError();
      return;

    case Decryptor::kNoKey:
      if (retry_on_no_key_) {
        retry_on_no_key_ = false;
        DecryptNextBuffer();
      } else {
        state_ = State::kWaitingKey;
        sink_->OnSysmemBufferStreamNoKey();
      }
      return;

    case Decryptor::kNeedMoreData:
      break;

    case Decryptor::kSuccess:
      passthrough_stream_.EnqueueBuffer(std::move(decrypted_buffer));
  }

  buffer_queue_.pop_front();

  DecryptNextBuffer();
}

}  // namespace media
