// Copyright (c) 2012 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 "net/base/upload_file_element_reader.h"

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

namespace net {

namespace {

// In tests, this value is used to override the return value of
// UploadFileElementReader::GetContentLength() when set to non-zero.
uint64_t overriding_content_length = 0;

}  // namespace

UploadFileElementReader::UploadFileElementReader(
    base::TaskRunner* task_runner,
    base::File file,
    const base::FilePath& path,
    uint64_t range_offset,
    uint64_t range_length,
    const base::Time& expected_modification_time)
    : task_runner_(task_runner),
      path_(path),
      range_offset_(range_offset),
      range_length_(range_length),
      expected_modification_time_(expected_modification_time),
      content_length_(0),
      bytes_remaining_(0),
      next_state_(State::IDLE),
      init_called_while_operation_pending_(false),
      weak_ptr_factory_(this) {
  DCHECK(file.IsValid());
  DCHECK(task_runner_.get());
  file_stream_ = std::make_unique<FileStream>(std::move(file), task_runner);
}

UploadFileElementReader::UploadFileElementReader(
    base::TaskRunner* task_runner,
    const base::FilePath& path,
    uint64_t range_offset,
    uint64_t range_length,
    const base::Time& expected_modification_time)
    : task_runner_(task_runner),
      path_(path),
      range_offset_(range_offset),
      range_length_(range_length),
      expected_modification_time_(expected_modification_time),
      content_length_(0),
      bytes_remaining_(0),
      next_state_(State::IDLE),
      init_called_while_operation_pending_(false),
      weak_ptr_factory_(this) {
  DCHECK(task_runner_.get());
}

UploadFileElementReader::~UploadFileElementReader() = default;

const UploadFileElementReader* UploadFileElementReader::AsFileReader() const {
  return this;
}

int UploadFileElementReader::Init(CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());

  bytes_remaining_ = 0;
  content_length_ = 0;
  pending_callback_.Reset();

  // If the file is being opened, just update the callback, and continue
  // waiting.
  if (next_state_ == State::OPEN_COMPLETE) {
    DCHECK(file_stream_);
    pending_callback_ = std::move(callback);
    return ERR_IO_PENDING;
  }

  // If there's already a pending operation, wait for it to complete before
  // restarting the request.
  if (next_state_ != State::IDLE) {
    init_called_while_operation_pending_ = true;
    pending_callback_ = std::move(callback);
    return ERR_IO_PENDING;
  }

  DCHECK(!init_called_while_operation_pending_);

  if (file_stream_) {
    // If the file is already open, just re-use it.
    // TODO(mmenke): Consider reusing file info, too.
    next_state_ = State::SEEK;
  } else {
    next_state_ = State::OPEN;
  }
  int result = DoLoop(OK);
  if (result == ERR_IO_PENDING)
    pending_callback_ = std::move(callback);
  return result;
}

uint64_t UploadFileElementReader::GetContentLength() const {
  if (overriding_content_length)
    return overriding_content_length;
  return content_length_;
}

uint64_t UploadFileElementReader::BytesRemaining() const {
  return bytes_remaining_;
}

int UploadFileElementReader::Read(IOBuffer* buf,
                                  int buf_length,
                                  CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  DCHECK_EQ(next_state_, State::IDLE);
  DCHECK(file_stream_);

  int num_bytes_to_read = static_cast<int>(
      std::min(BytesRemaining(), static_cast<uint64_t>(buf_length)));
  if (num_bytes_to_read == 0)
    return 0;

  next_state_ = State::READ_COMPLETE;
  int result = file_stream_->Read(
      buf, num_bytes_to_read,
      base::BindOnce(base::IgnoreResult(&UploadFileElementReader::OnIOComplete),
                     weak_ptr_factory_.GetWeakPtr()));

  if (result != ERR_IO_PENDING)
    result = DoLoop(result);

  if (result == ERR_IO_PENDING)
    pending_callback_ = std::move(callback);

  return result;
}

int UploadFileElementReader::DoLoop(int result) {
  DCHECK_NE(result, ERR_IO_PENDING);

  if (init_called_while_operation_pending_) {
    // File should already have been opened successfully.
    DCHECK_NE(next_state_, State::OPEN_COMPLETE);

    next_state_ = State::SEEK;
    init_called_while_operation_pending_ = false;
    result = net::OK;
  }

  while (next_state_ != State::IDLE && result != ERR_IO_PENDING) {
    State state = next_state_;
    next_state_ = State::IDLE;
    switch (state) {
      case State::IDLE:
        NOTREACHED();
        break;
      case State::OPEN:
        // Ignore previous result here. It's typically OK, but if Init()
        // interrupted the previous operation, it may be an error.
        result = DoOpen();
        break;
      case State::OPEN_COMPLETE:
        result = DoOpenComplete(result);
        break;
      case State::SEEK:
        DCHECK_EQ(OK, result);
        result = DoSeek();
        break;
      case State::GET_FILE_INFO:
        result = DoGetFileInfo(result);
        break;
      case State::GET_FILE_INFO_COMPLETE:
        result = DoGetFileInfoComplete(result);
        break;

      case State::READ_COMPLETE:
        result = DoReadComplete(result);
        break;
    }
  }

  return result;
}

int UploadFileElementReader::DoOpen() {
  DCHECK(!file_stream_);

  next_state_ = State::OPEN_COMPLETE;

  file_stream_.reset(new FileStream(task_runner_.get()));
  int result = file_stream_->Open(
      path_,
      base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC,
      base::BindOnce(&UploadFileElementReader::OnIOComplete,
                     weak_ptr_factory_.GetWeakPtr()));
  DCHECK_GT(0, result);
  return result;
}

int UploadFileElementReader::DoOpenComplete(int result) {
  if (result < 0) {
    DLOG(WARNING) << "Failed to open \"" << path_.value()
                  << "\" for reading: " << result;
    file_stream_.reset();
    return result;
  }

  if (range_offset_) {
    next_state_ = State::SEEK;
  } else {
    next_state_ = State::GET_FILE_INFO;
  }
  return net::OK;
}

int UploadFileElementReader::DoSeek() {
  next_state_ = State::GET_FILE_INFO;
  return file_stream_->Seek(
      range_offset_,
      base::BindOnce(
          [](base::WeakPtr<UploadFileElementReader> weak_this, int64_t result) {
            if (!weak_this)
              return;
            weak_this->OnIOComplete(result >= 0 ? OK
                                                : static_cast<int>(result));
          },
          weak_ptr_factory_.GetWeakPtr()));
}

int UploadFileElementReader::DoGetFileInfo(int result) {
  if (result < 0) {
    DLOG(WARNING) << "Failed to seek \"" << path_.value()
                  << "\" to offset: " << range_offset_ << " (" << result << ")";
    return result;
  }

  next_state_ = State::GET_FILE_INFO_COMPLETE;

  base::File::Info* owned_file_info = new base::File::Info;
  result = file_stream_->GetFileInfo(
      owned_file_info,
      base::BindOnce(
          [](base::WeakPtr<UploadFileElementReader> weak_this,
             base::File::Info* file_info, int result) {
            if (!weak_this)
              return;
            weak_this->file_info_ = *file_info;
            weak_this->OnIOComplete(result);
          },
          weak_ptr_factory_.GetWeakPtr(), base::Owned(owned_file_info)));
  // GetFileInfo() can't succeed synchronously.
  DCHECK_NE(result, OK);
  return result;
}

int UploadFileElementReader::DoGetFileInfoComplete(int result) {
  if (result != OK) {
    DLOG(WARNING) << "Failed to get file info of \"" << path_.value() << "\"";
    return result;
  }

  int64_t length = file_info_.size;
  if (range_offset_ < static_cast<uint64_t>(length)) {
    // Compensate for the offset.
    length = std::min(length - range_offset_, range_length_);
  }

  // If the underlying file has been changed and the expected file modification
  // time is set, treat it as error. Note that |expected_modification_time_| may
  // have gone through multiple conversion steps involving loss of precision
  // (including conversion to time_t). Therefore the check below only verifies
  // that the timestamps are within one second of each other. This check is used
  // for sliced files.
  if (!expected_modification_time_.is_null() &&
      (expected_modification_time_ - file_info_.last_modified)
              .magnitude()
              .InSeconds() != 0) {
    return ERR_UPLOAD_FILE_CHANGED;
  }

  content_length_ = length;
  bytes_remaining_ = GetContentLength();
  return result;
}

int UploadFileElementReader::DoReadComplete(int result) {
  if (result == 0)  // Reached end-of-file earlier than expected.
    return ERR_UPLOAD_FILE_CHANGED;

  if (result > 0) {
    DCHECK_GE(bytes_remaining_, static_cast<uint64_t>(result));
    bytes_remaining_ -= result;
  }

  return result;
}

void UploadFileElementReader::OnIOComplete(int result) {
  DCHECK(pending_callback_);

  result = DoLoop(result);

  if (result != ERR_IO_PENDING)
    std::move(pending_callback_).Run(result);
}

UploadFileElementReader::ScopedOverridingContentLengthForTests::
    ScopedOverridingContentLengthForTests(uint64_t value) {
  overriding_content_length = value;
}

UploadFileElementReader::ScopedOverridingContentLengthForTests::
~ScopedOverridingContentLengthForTests() {
  overriding_content_length = 0;
}

}  // namespace net
