// Copyright 2018 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/browser/devtools/devtools_stream_file.h"

#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/task/lazy_task_runner.h"
#include "base/task/post_task.h"
#include "base/third_party/icu/icu_utf.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/fileapi/file_system_context.h"

namespace content {

scoped_refptr<base::SequencedTaskRunner> impl_task_runner() {
  constexpr base::TaskTraits kBlockingTraits = {
      base::MayBlock(), base::TaskPriority::BEST_EFFORT};
  static base::LazySequencedTaskRunner s_sequenced_task_unner =
      LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER(kBlockingTraits);
  return s_sequenced_task_unner.Get();
}

scoped_refptr<DevToolsStreamFile> DevToolsStreamFile::Create(
    DevToolsIOContext* context,
    bool binary) {
  return new DevToolsStreamFile(context, binary);
}

DevToolsStreamFile::DevToolsStreamFile(DevToolsIOContext* context, bool binary)
    : DevToolsIOContext::Stream(impl_task_runner()),
      handle_(Register(context)),
      binary_(binary),
      task_runner_(impl_task_runner()),
      had_errors_(false),
      last_read_pos_(0) {}

DevToolsStreamFile::~DevToolsStreamFile() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
}

bool DevToolsStreamFile::InitOnFileSequenceIfNeeded() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  if (had_errors_)
    return false;
  if (file_.IsValid())
    return true;
  base::FilePath temp_path;
  if (!base::CreateTemporaryFile(&temp_path)) {
    LOG(ERROR) << "Failed to create temporary file";
    had_errors_ = true;
    return false;
  }
  const unsigned flags = base::File::FLAG_OPEN_TRUNCATED |
                         base::File::FLAG_WRITE | base::File::FLAG_READ |
                         base::File::FLAG_DELETE_ON_CLOSE;
  file_.Initialize(temp_path, flags);
  if (!file_.IsValid()) {
    LOG(ERROR) << "Failed to open temporary file: " << temp_path.value() << ", "
               << base::File::ErrorToString(file_.error_details());
    had_errors_ = true;
    DeleteFile(temp_path, false);
    return false;
  }
  return true;
}

void DevToolsStreamFile::Read(off_t position,
                              size_t max_size,
                              ReadCallback callback) {
  task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&DevToolsStreamFile::ReadOnFileSequence, this,
                                position, max_size, std::move(callback)));
}

void DevToolsStreamFile::Append(std::unique_ptr<std::string> data) {
  task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&DevToolsStreamFile::AppendOnFileSequence, this,
                                std::move(data)));
}

void DevToolsStreamFile::ReadOnFileSequence(off_t position,
                                            size_t max_size,
                                            ReadCallback callback) {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  Status status = StatusFailure;
  std::unique_ptr<std::string> data;
  bool base64_encoded = false;

  if (file_.IsValid()) {
    std::string buffer;
    buffer.resize(max_size);
    if (position < 0)
      position = last_read_pos_;
    int size_got = file_.ReadNoBestEffort(position, &*buffer.begin(), max_size);
    if (size_got < 0) {
      LOG(ERROR) << "Failed to read temporary file";
      had_errors_ = true;
      file_.Close();
    } else {
      // Provided client has requested sufficient large block, make their
      // life easier by not truncating in the middle of a UTF-8 character.
      if (size_got > 6 && !CBU8_IS_SINGLE(buffer[size_got - 1])) {
        base::TruncateUTF8ToByteSize(buffer, size_got, &buffer);
        size_got = buffer.size();
      } else {
        buffer.resize(size_got);
      }
      data.reset(new std::string(std::move(buffer)));
      status = size_got ? StatusSuccess : StatusEOF;
      last_read_pos_ = position + size_got;
    }
  }
  if (binary_) {
    std::string raw_data(std::move(*data));
    base::Base64Encode(raw_data, data.get());
    base64_encoded = true;
  }
  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
                           base::BindOnce(std::move(callback), std::move(data),
                                          base64_encoded, status));
}

void DevToolsStreamFile::AppendOnFileSequence(
    std::unique_ptr<std::string> data) {
  if (!InitOnFileSequenceIfNeeded())
    return;
  int size_written = file_.WriteAtCurrentPos(&*data->begin(), data->length());
  if (size_written != static_cast<int>(data->length())) {
    LOG(ERROR) << "Failed to write temporary file";
    had_errors_ = true;
    file_.Close();
  }
}

}  // namespace content
