// 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 "content/renderer/mhtml_handle_writer.h"

#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "content/common/download/mhtml_file_writer.mojom.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/blink/public/platform/web_thread_safe_data.h"

namespace content {

MHTMLHandleWriter::MHTMLHandleWriter(
    scoped_refptr<base::TaskRunner> main_thread_task_runner,
    MHTMLWriteCompleteCallback callback)
    : main_thread_task_runner_(std::move(main_thread_task_runner)),
      callback_(std::move(callback)) {}

MHTMLHandleWriter::~MHTMLHandleWriter() {}

void MHTMLHandleWriter::WriteContents(
    std::vector<blink::WebThreadSafeData> mhtml_contents) {
  TRACE_EVENT_ASYNC_BEGIN0("page-serialization",
                           "Writing MHTML contents to handle", this);
  DCHECK(mhtml_write_start_time_.is_null());
  mhtml_write_start_time_ = base::TimeTicks::Now();

  WriteContentsImpl(std::move(mhtml_contents));
}

void MHTMLHandleWriter::Finish(mojom::MhtmlSaveStatus save_status) {
  DCHECK(!RenderThread::IsMainThread())
      << "Should not run in the main renderer thread";

  // Only record UMA if WriteContents has been called.
  if (!mhtml_write_start_time_.is_null()) {
    TRACE_EVENT_ASYNC_END0("page-serialization",
                           "WriteContentsImpl (MHTMLHandleWriter)", this);
    base::TimeDelta mhtml_write_time =
        base::TimeTicks::Now() - mhtml_write_start_time_;
    UMA_HISTOGRAM_TIMES(
        "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame",
        mhtml_write_time);
  }

  Close();

  main_thread_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback_), save_status));
  delete this;
}

MHTMLFileHandleWriter::MHTMLFileHandleWriter(
    scoped_refptr<base::TaskRunner> main_thread_task_runner,
    MHTMLWriteCompleteCallback callback,
    base::File file)
    : MHTMLHandleWriter(std::move(main_thread_task_runner),
                        std::move(callback)),
      file_(std::move(file)) {}

MHTMLFileHandleWriter::~MHTMLFileHandleWriter() {}

void MHTMLFileHandleWriter::WriteContentsImpl(
    std::vector<blink::WebThreadSafeData> mhtml_contents) {
  mojom::MhtmlSaveStatus save_status = mojom::MhtmlSaveStatus::kSuccess;
  for (const blink::WebThreadSafeData& data : mhtml_contents) {
    if (!data.IsEmpty() &&
        file_.WriteAtCurrentPos(data.Data(), data.size()) < 0) {
      save_status = mojom::MhtmlSaveStatus::kFileWritingError;
      break;
    }
  }
  Finish(save_status);
}

void MHTMLFileHandleWriter::Close() {
  file_.Close();
}

MHTMLProducerHandleWriter::MHTMLProducerHandleWriter(
    scoped_refptr<base::TaskRunner> main_thread_task_runner,
    MHTMLWriteCompleteCallback callback,
    mojo::ScopedDataPipeProducerHandle producer)
    : MHTMLHandleWriter(std::move(main_thread_task_runner),
                        std::move(callback)),
      producer_(std::move(producer)),
      current_block_(0),
      write_position_(0) {}

void MHTMLProducerHandleWriter::WriteContentsImpl(
    std::vector<blink::WebThreadSafeData> mhtml_contents) {
  DCHECK(mhtml_contents_.empty());
  mhtml_contents_ = std::move(mhtml_contents);

  scoped_refptr<base::SequencedTaskRunner> task_runner =
      base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});

  task_runner->PostTask(
      FROM_HERE, base::BindOnce(&MHTMLProducerHandleWriter::BeginWatchingHandle,
                                base::Unretained(this)));
}

MHTMLProducerHandleWriter::~MHTMLProducerHandleWriter() {}

void MHTMLProducerHandleWriter::Close() {
  producer_.reset();
}

void MHTMLProducerHandleWriter::BeginWatchingHandle() {
  // mojo::SimpleWatcher's constructor by default gets a reference ptr
  // to the current SequencedTaskRunner if one is not specified, keeping
  // the current SequencedTaskRunner's lifetime bound to |watcher_|.
  watcher_ = std::make_unique<mojo::SimpleWatcher>(
      FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC);
  // Using base::Unretained is safe, as |this| owns |watcher_|.
  watcher_->Watch(
      producer_.get(),
      MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
      MOJO_WATCH_CONDITION_SATISFIED,
      base::BindRepeating(&MHTMLProducerHandleWriter::TryWritingContents,
                          base::Unretained(this)));
}

// TODO(https://crbug.com/915966): This can be simplified with usage
// of BlockingCopyToString once error signalling is implemented and
// updated with usage of base::span instead of std::string.
void MHTMLProducerHandleWriter::TryWritingContents(
    MojoResult result,
    const mojo::HandleSignalsState& state) {
  if (result != MOJO_RESULT_OK) {
    DLOG(ERROR)
        << "Error receiving notifications from producer handle watcher.";
    Finish(mojom::MhtmlSaveStatus::kStreamingError);
    return;
  }

  while (true) {
    const blink::WebThreadSafeData& data = mhtml_contents_.at(current_block_);

    // If there is no more data in this block, continue to next block or
    // finish.
    uint32_t num_bytes = data.size() - write_position_;
    if (num_bytes == 0) {
      write_position_ = 0;
      if (++current_block_ >= mhtml_contents_.size()) {
        Finish(mojom::MhtmlSaveStatus::kSuccess);
        return;
      }
      continue;
    }

    result = producer_->WriteData(data.Data() + write_position_, &num_bytes,
                                  MOJO_WRITE_DATA_FLAG_NONE);

    // Break out of loop early if write was not successful to avoid
    // incrementing the write position incorrectly.
    if (result != MOJO_RESULT_OK)
      break;

    // Reaching this indicates a successful write.
    write_position_ += num_bytes;
    DCHECK(write_position_ <= data.size());
  }

  if (result != MOJO_RESULT_SHOULD_WAIT) {
    Finish(mojom::MhtmlSaveStatus::kStreamingError);
  }

  // Buffer is full, return to automatically re-arm the watcher.
}

}  // namespace content