// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "chrome/browser/webshare/store_file_task.h"

#include "base/containers/span.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/net_errors.h"

namespace {
bool g_skip_copying_for_testing = false;
}  // namespace

namespace webshare {

StoreFileTask::StoreFileTask(base::FilePath filename,
                             blink::mojom::SharedFilePtr file,
                             uint64_t& available_space,
                             blink::mojom::ShareService::ShareCallback callback)
    : filename_(std::move(filename)),
      file_(std::move(file)),
      available_space_(available_space),
      callback_(std::move(callback)),
      read_pipe_watcher_(FROM_HERE,
                         mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
  // |filename| is generated by GenerateFileName().
  DCHECK(!filename_.ReferencesParent());
  DCHECK(filename_.BaseName().MaybeAsASCII().find("share") >= 0);
}

StoreFileTask::~StoreFileTask() = default;

void StoreFileTask::Start() {
  {
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);
    output_file_.Initialize(
        filename_, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
  }

  if (g_skip_copying_for_testing) {
    std::move(callback_).Run(blink::mojom::ShareError::OK);
    return;
  }

  StartRead();
}

void StoreFileTask::StartRead() {
  constexpr size_t kDataPipeCapacity = 65536;

  MojoCreateDataPipeOptions options;
  options.struct_size = sizeof(MojoCreateDataPipeOptions);
  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
  options.element_num_bytes = 1;
  options.capacity_num_bytes = kDataPipeCapacity;

  mojo::ScopedDataPipeProducerHandle producer_handle;
  MojoResult rv = CreateDataPipe(&options, producer_handle, consumer_handle_);
  if (rv != MOJO_RESULT_OK) {
    std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
    return;
  }

  mojo::Remote<blink::mojom::Blob> blob(std::move(file_->blob->blob));
  blob->ReadAll(std::move(producer_handle),
                receiver_.BindNewPipeAndPassRemote());
}

// static
void StoreFileTask::SkipCopyingForTesting() {
  g_skip_copying_for_testing = true;
}

void StoreFileTask::OnDataPipeReadable(MojoResult result) {
  if (result != MOJO_RESULT_OK) {
    if (!received_all_data_) {
      std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
    }
    return;
  }

  while (true) {
    base::span<const uint8_t> buffer;
    MojoResult pipe_result =
        consumer_handle_->BeginReadData(MOJO_READ_DATA_FLAG_NONE, buffer);
    if (pipe_result == MOJO_RESULT_SHOULD_WAIT)
      return;

    if (pipe_result == MOJO_RESULT_FAILED_PRECONDITION) {
      // Pipe closed.
      if (!received_all_data_) {
        std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
      }
      return;
    }
    if (pipe_result != MOJO_RESULT_OK) {
      std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
      return;
    }

    // Defend against compromised renderer process sending too much data.
    std::string_view chars = base::as_string_view(buffer);
    int chars_size_int = base::saturated_cast<int>(chars.size());
    if (buffer.size() > total_bytes_ - bytes_received_ ||
        output_file_.WriteAtCurrentPos(chars.data(), chars_size_int) !=
            chars_size_int) {
      std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
      return;
    }
    bytes_received_ += buffer.size();
    DCHECK_LE(bytes_received_, total_bytes_);

    consumer_handle_->EndReadData(buffer.size());
    if (bytes_received_ == total_bytes_) {
      received_all_data_ = true;
      if (received_on_complete_)
        OnSuccess();
      return;
    }
  }
}

void StoreFileTask::OnSuccess() {
  DCHECK_EQ(bytes_received_, total_bytes_);

  std::move(callback_).Run(blink::mojom::ShareError::OK);
}

void StoreFileTask::OnCalculatedSize(uint64_t total_size,
                                     uint64_t expected_content_size) {
  DCHECK_EQ(total_size, expected_content_size);

  if (expected_content_size > *available_space_ ||
      expected_content_size != file_->blob->size) {
    VLOG(1) << "Share too large: " << expected_content_size << " bytes";
    std::move(callback_).Run(blink::mojom::ShareError::PERMISSION_DENIED);
    return;
  }

  *available_space_ -= expected_content_size;
  total_bytes_ = expected_content_size;

  if (expected_content_size == 0) {
    received_all_data_ = true;
    return;
  }

  read_pipe_watcher_.Watch(
      consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
      base::BindRepeating(&StoreFileTask::OnDataPipeReadable,
                          weak_ptr_factory_.GetWeakPtr()));
}

void StoreFileTask::OnComplete(int32_t status, uint64_t data_length) {
  if (status != net::OK || data_length != total_bytes_) {
    std::move(callback_).Run(blink::mojom::ShareError::INTERNAL_ERROR);
    return;
  }

  received_on_complete_ = true;
  if (received_all_data_)
    OnSuccess();
}

}  // namespace webshare
