// Copyright 2016 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 "pdf/url_loader_wrapper_impl.h"

#include <memory>

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "net/http/http_util.h"
#include "pdf/timer.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/url_response_info.h"

namespace chrome_pdf {

namespace {
// We should read with delay to prevent block UI thread, and reduce CPU usage.
const int kReadDelayMs = 2;

pp::URLRequestInfo MakeRangeRequest(pp::Instance* plugin_instance,
                                    const std::string& url,
                                    const std::string& referrer_url,
                                    uint32_t position,
                                    uint32_t size) {
  pp::URLRequestInfo request(plugin_instance);
  request.SetURL(url);
  request.SetMethod("GET");
  request.SetFollowRedirects(false);
  request.SetCustomReferrerURL(referrer_url);

  // According to rfc2616, byte range specifies position of the first and last
  // bytes in the requested range inclusively. Therefore we should subtract 1
  // from the position + size, to get index of the last byte that needs to be
  // downloaded.
  std::string str_header =
      base::StringPrintf("Range: bytes=%d-%d", position, position + size - 1);
  pp::Var header(str_header.c_str());
  request.SetHeaders(header);

  return request;
}

bool GetByteRangeFromStr(const std::string& content_range_str,
                         int* start,
                         int* end) {
  std::string range = content_range_str;
  if (!base::StartsWith(range, "bytes", base::CompareCase::INSENSITIVE_ASCII))
    return false;

  range = range.substr(strlen("bytes"));
  std::string::size_type pos = range.find('-');
  std::string range_end;
  if (pos != std::string::npos)
    range_end = range.substr(pos + 1);
  base::TrimWhitespaceASCII(range, base::TRIM_LEADING, &range);
  base::TrimWhitespaceASCII(range_end, base::TRIM_LEADING, &range_end);
  *start = atoi(range.c_str());
  *end = atoi(range_end.c_str());
  return true;
}

// If the headers have a byte-range response, writes the start and end
// positions and returns true if at least the start position was parsed.
// The end position will be set to 0 if it was not found or parsed from the
// response.
// Returns false if not even a start position could be parsed.
bool GetByteRangeFromHeaders(const std::string& headers, int* start, int* end) {
  net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
  while (it.GetNext()) {
    if (base::LowerCaseEqualsASCII(it.name(), "content-range")) {
      if (GetByteRangeFromStr(it.values().c_str(), start, end))
        return true;
    }
  }
  return false;
}

bool IsDoubleEndLineAtEnd(const char* buffer, int size) {
  if (size < 2)
    return false;

  if (buffer[size - 1] == '\n' && buffer[size - 2] == '\n')
    return true;

  if (size < 4)
    return false;

  return buffer[size - 1] == '\n' && buffer[size - 2] == '\r' &&
         buffer[size - 3] == '\n' && buffer[size - 4] == '\r';
}

}  // namespace

class URLLoaderWrapperImpl::ReadStarter : public Timer {
 public:
  explicit ReadStarter(URLLoaderWrapperImpl* owner)
      : Timer(kReadDelayMs), owner_(owner) {}
  ~ReadStarter() override = default;

  // Timer overrides:
  void OnTimer() override { owner_->ReadResponseBodyImpl(); }

 private:
  URLLoaderWrapperImpl* owner_;
};

URLLoaderWrapperImpl::URLLoaderWrapperImpl(pp::Instance* plugin_instance,
                                           const pp::URLLoader& url_loader)
    : plugin_instance_(plugin_instance),
      url_loader_(url_loader),
      callback_factory_(this) {
  SetHeadersFromLoader();
}

URLLoaderWrapperImpl::~URLLoaderWrapperImpl() {
  Close();
  // We should call callbacks to prevent memory leaks.
  // The callbacks don't do anything, because the objects that created the
  // callbacks have been destroyed.
  if (!did_open_callback_.IsOptional())
    did_open_callback_.RunAndClear(-1);
  if (!did_read_callback_.IsOptional())
    did_read_callback_.RunAndClear(-1);
}

int URLLoaderWrapperImpl::GetContentLength() const {
  return content_length_;
}

bool URLLoaderWrapperImpl::IsAcceptRangesBytes() const {
  return accept_ranges_bytes_;
}

bool URLLoaderWrapperImpl::IsContentEncoded() const {
  return content_encoded_;
}

std::string URLLoaderWrapperImpl::GetContentType() const {
  return content_type_;
}
std::string URLLoaderWrapperImpl::GetContentDisposition() const {
  return content_disposition_;
}

int URLLoaderWrapperImpl::GetStatusCode() const {
  return url_loader_.GetResponseInfo().GetStatusCode();
}

bool URLLoaderWrapperImpl::IsMultipart() const {
  return is_multipart_;
}

bool URLLoaderWrapperImpl::GetByteRange(int* start, int* end) const {
  DCHECK(start);
  DCHECK(end);
  *start = byte_range_.start();
  *end = byte_range_.end();
  return byte_range_.IsValid();
}

bool URLLoaderWrapperImpl::GetDownloadProgress(
    int64_t* bytes_received,
    int64_t* total_bytes_to_be_received) const {
  return url_loader_.GetDownloadProgress(bytes_received,
                                         total_bytes_to_be_received);
}

void URLLoaderWrapperImpl::Close() {
  url_loader_.Close();
  read_starter_.reset();
}

void URLLoaderWrapperImpl::OpenRange(const std::string& url,
                                     const std::string& referrer_url,
                                     uint32_t position,
                                     uint32_t size,
                                     const pp::CompletionCallback& cc) {
  did_open_callback_ = cc;
  pp::CompletionCallback callback =
      callback_factory_.NewCallback(&URLLoaderWrapperImpl::DidOpen);
  int rv = url_loader_.Open(
      MakeRangeRequest(plugin_instance_, url, referrer_url, position, size),
      callback);
  if (rv != PP_OK_COMPLETIONPENDING)
    callback.Run(rv);
}

void URLLoaderWrapperImpl::ReadResponseBody(char* buffer,
                                            int buffer_size,
                                            const pp::CompletionCallback& cc) {
  did_read_callback_ = cc;
  buffer_ = buffer;
  buffer_size_ = buffer_size;
  read_starter_ = std::make_unique<ReadStarter>(this);
}

void URLLoaderWrapperImpl::ReadResponseBodyImpl() {
  read_starter_.reset();
  pp::CompletionCallback callback =
      callback_factory_.NewCallback(&URLLoaderWrapperImpl::DidRead);
  int rv = url_loader_.ReadResponseBody(buffer_, buffer_size_, callback);
  if (rv != PP_OK_COMPLETIONPENDING) {
    callback.Run(rv);
  }
}

void URLLoaderWrapperImpl::SetResponseHeaders(
    const std::string& response_headers) {
  response_headers_ = response_headers;
  ParseHeaders();
}

void URLLoaderWrapperImpl::ParseHeaders() {
  content_length_ = -1;
  accept_ranges_bytes_ = false;
  content_encoded_ = false;
  content_type_.clear();
  content_disposition_.clear();
  multipart_boundary_.clear();
  byte_range_ = gfx::Range::InvalidRange();
  is_multipart_ = false;

  if (response_headers_.empty())
    return;

  net::HttpUtil::HeadersIterator it(response_headers_.begin(),
                                    response_headers_.end(), "\n");
  while (it.GetNext()) {
    if (base::LowerCaseEqualsASCII(it.name(), "content-length")) {
      content_length_ = atoi(it.values().c_str());
    } else if (base::LowerCaseEqualsASCII(it.name(), "accept-ranges")) {
      accept_ranges_bytes_ = base::LowerCaseEqualsASCII(it.values(), "bytes");
    } else if (base::LowerCaseEqualsASCII(it.name(), "content-encoding")) {
      content_encoded_ = true;
    } else if (base::LowerCaseEqualsASCII(it.name(), "content-type")) {
      content_type_ = it.values();
      size_t semi_colon_pos = content_type_.find(';');
      if (semi_colon_pos != std::string::npos) {
        content_type_ = content_type_.substr(0, semi_colon_pos);
      }
      base::TrimWhitespaceASCII(content_type_, base::TRIM_ALL, &content_type_);
      // multipart boundary.
      std::string type = base::ToLowerASCII(it.values());
      if (base::StartsWith(type, "multipart/", base::CompareCase::SENSITIVE)) {
        const char* boundary = strstr(type.c_str(), "boundary=");
        DCHECK(boundary);
        if (boundary) {
          multipart_boundary_ = std::string(boundary + 9);
          is_multipart_ = !multipart_boundary_.empty();
        }
      }
    } else if (base::LowerCaseEqualsASCII(it.name(), "content-disposition")) {
      content_disposition_ = it.values();
    } else if (base::LowerCaseEqualsASCII(it.name(), "content-range")) {
      int start = 0;
      int end = 0;
      if (GetByteRangeFromStr(it.values().c_str(), &start, &end)) {
        byte_range_ = gfx::Range(start, end);
      }
    }
  }
}

void URLLoaderWrapperImpl::DidOpen(int32_t result) {
  SetHeadersFromLoader();
  did_open_callback_.RunAndClear(result);
}

void URLLoaderWrapperImpl::DidRead(int32_t result) {
  if (multi_part_processed_) {
    // Reset this flag so we look inside the buffer in calls of DidRead for this
    // response only once.  Note that this code DOES NOT handle multi part
    // responses with more than one part (we don't issue them at the moment, so
    // they shouldn't arrive).
    is_multipart_ = false;
  }
  if (result <= 0 || !is_multipart_) {
    did_read_callback_.RunAndClear(result);
    return;
  }
  if (result <= 2) {
    // TODO(art-snake): Accumulate data for parse headers.
    did_read_callback_.RunAndClear(result);
    return;
  }

  char* start = buffer_;
  size_t length = result;
  multi_part_processed_ = true;
  for (int i = 2; i < result; ++i) {
    if (IsDoubleEndLineAtEnd(buffer_, i)) {
      int start_pos = 0;
      int end_pos = 0;
      if (GetByteRangeFromHeaders(std::string(buffer_, i), &start_pos,
                                  &end_pos)) {
        byte_range_ = gfx::Range(start_pos, end_pos);
        start += i;
        length -= i;
      }
      break;
    }
  }
  result = length;
  if (result == 0) {
    // Continue receiving.
    return ReadResponseBodyImpl();
  }
  DCHECK_GT(result, 0);
  memmove(buffer_, start, result);

  did_read_callback_.RunAndClear(result);
}

void URLLoaderWrapperImpl::SetHeadersFromLoader() {
  pp::URLResponseInfo response = url_loader_.GetResponseInfo();
  pp::Var headers_var = response.GetHeaders();

  SetResponseHeaders(headers_var.is_string() ? headers_var.AsString() : "");
}

}  // namespace chrome_pdf
