//
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/common/file_fetcher.h"

#include <algorithm>
#include <string>

#include <base/bind.h>
#include <base/format_macros.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/streams/file_stream.h>

#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/platform_constants.h"

using std::string;

namespace {

size_t kReadBufferSize = 16 * 1024;

}  // namespace

namespace chromeos_update_engine {

// static
bool FileFetcher::SupportedUrl(const string& url) {
  // Note that we require the file path to start with a "/".
  return (
      base::StartsWith(url, "file:///", base::CompareCase::INSENSITIVE_ASCII) ||
      base::StartsWith(url, "fd://", base::CompareCase::INSENSITIVE_ASCII));
}

FileFetcher::~FileFetcher() {
  LOG_IF(ERROR, transfer_in_progress_)
      << "Destroying the fetcher while a transfer is in progress.";
  CleanUp();
}

// Begins the transfer, which must not have already been started.
void FileFetcher::BeginTransfer(const string& url) {
  CHECK(!transfer_in_progress_);

  if (!SupportedUrl(url)) {
    LOG(ERROR) << "Unsupported file URL: " << url;
    // No HTTP error code when the URL is not supported.
    http_response_code_ = 0;
    CleanUp();
    if (delegate_)
      delegate_->TransferComplete(this, false);
    return;
  }

  string file_path;

  if (base::StartsWith(url, "fd://", base::CompareCase::INSENSITIVE_ASCII)) {
    int fd = std::stoi(url.substr(strlen("fd://")));
    file_path = url;
    stream_ = brillo::FileStream::FromFileDescriptor(fd, false, nullptr);
  } else {
    file_path = url.substr(strlen("file://"));
    stream_ =
        brillo::FileStream::Open(base::FilePath(file_path),
                                 brillo::Stream::AccessMode::READ,
                                 brillo::FileStream::Disposition::OPEN_EXISTING,
                                 nullptr);
  }

  if (!stream_) {
    LOG(ERROR) << "Couldn't open " << file_path;
    http_response_code_ = kHttpResponseNotFound;
    CleanUp();
    if (delegate_)
      delegate_->TransferComplete(this, false);
    return;
  }
  http_response_code_ = kHttpResponseOk;

  if (offset_)
    stream_->SetPosition(offset_, nullptr);
  bytes_copied_ = 0;
  transfer_in_progress_ = true;
  ScheduleRead();
}

void FileFetcher::TerminateTransfer() {
  CleanUp();
  if (delegate_) {
    // Note that after the callback returns this object may be destroyed.
    delegate_->TransferTerminated(this);
  }
}

void FileFetcher::ScheduleRead() {
  if (transfer_paused_ || ongoing_read_ || !transfer_in_progress_)
    return;

  buffer_.resize(kReadBufferSize);
  size_t bytes_to_read = buffer_.size();
  if (data_length_ >= 0) {
    bytes_to_read = std::min(static_cast<uint64_t>(bytes_to_read),
                             data_length_ - bytes_copied_);
  }

  if (!bytes_to_read) {
    OnReadDoneCallback(0);
    return;
  }

  ongoing_read_ = stream_->ReadAsync(
      buffer_.data(),
      bytes_to_read,
      base::Bind(&FileFetcher::OnReadDoneCallback, base::Unretained(this)),
      base::Bind(&FileFetcher::OnReadErrorCallback, base::Unretained(this)),
      nullptr);

  if (!ongoing_read_) {
    LOG(ERROR) << "Unable to schedule an asynchronous read from the stream.";
    CleanUp();
    if (delegate_)
      delegate_->TransferComplete(this, false);
  }
}

void FileFetcher::OnReadDoneCallback(size_t bytes_read) {
  ongoing_read_ = false;
  if (bytes_read == 0) {
    CleanUp();
    if (delegate_)
      delegate_->TransferComplete(this, true);
  } else {
    bytes_copied_ += bytes_read;
    if (delegate_ &&
        !delegate_->ReceivedBytes(this, buffer_.data(), bytes_read))
      return;
    ScheduleRead();
  }
}

void FileFetcher::OnReadErrorCallback(const brillo::Error* error) {
  LOG(ERROR) << "Asynchronous read failed: " << error->GetMessage();
  CleanUp();
  if (delegate_)
    delegate_->TransferComplete(this, false);
}

void FileFetcher::Pause() {
  if (transfer_paused_) {
    LOG(ERROR) << "Fetcher already paused.";
    return;
  }
  transfer_paused_ = true;
}

void FileFetcher::Unpause() {
  if (!transfer_paused_) {
    LOG(ERROR) << "Resume attempted when fetcher not paused.";
    return;
  }
  transfer_paused_ = false;
  ScheduleRead();
}

void FileFetcher::CleanUp() {
  if (stream_) {
    stream_->CancelPendingAsyncOperations();
    stream_->CloseBlocking(nullptr);
    stream_.reset();
  }
  // Destroying the |stream_| releases the callback, so we don't have any
  // ongoing read at this point.
  ongoing_read_ = false;
  buffer_ = brillo::Blob();

  transfer_in_progress_ = false;
  transfer_paused_ = false;
}
}  // namespace chromeos_update_engine
