// Copyright 2019 The Cobalt Authors. All Rights Reserved.
// Copyright 2019 Google Inc. All Rights Reserved.
//
// 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 "cobalt/loader/url_fetcher_string_writer.h"

#include "base/logging.h"
#include "net/base/net_errors.h"

namespace cobalt {
namespace loader {

// URLFetcherStringWriter::URLFetcherStringWriter(OnWriteCallback
// callback, base::TaskRunner* consumer_task_runner) :
// on_write_callback_(callback), consumer_task_runner_(consumer_task_runner) {
//   DCHECK(consumer_task_runner);
// }

namespace {
const int64_t kPreAllocateThreshold = 64 * 1024;
}  // namespace

URLFetcherStringWriter::URLFetcherStringWriter() = default;

URLFetcherStringWriter::~URLFetcherStringWriter() = default;

int URLFetcherStringWriter::Initialize(net::CompletionOnceCallback callback) {
  return net::OK;
}

void URLFetcherStringWriter::OnResponseStarted(int64_t content_length) {
  base::AutoLock auto_lock(lock_);

  if (content_length >= 0) {
    content_length_ = content_length;
  }
}

bool URLFetcherStringWriter::HasData() const {
  base::AutoLock auto_lock(lock_);
  return !data_.empty();
}

void URLFetcherStringWriter::GetAndResetData(std::string* data) {
  DCHECK(data);

  std::string empty;
  data->swap(empty);

  base::AutoLock auto_lock(lock_);
  data_.swap(*data);
}

int URLFetcherStringWriter::Write(net::IOBuffer* buffer, int num_bytes,
                                  net::CompletionOnceCallback callback) {
  base::AutoLock auto_lock(lock_);

  if (content_offset_ == 0 && num_bytes <= content_length_) {
    // Pre-allocate the whole buffer for small downloads, hope that all data can
    // be downloaded before GetAndResetData() is called.
    if (content_length_ <= kPreAllocateThreshold) {
      data_.reserve(content_length_);
    } else {
      data_.reserve(kPreAllocateThreshold);
    }
  }

  if (content_length_ > 0 && content_length_ > content_offset_ &&
      data_.size() + num_bytes > data_.capacity()) {
    // There is not enough memory allocated, and std::string is going to double
    // the allocation.  So a content in "1M + 1" bytes may end up allocating 2M
    // bytes.  Try to reserve the proper size to avoid this.
    auto content_remaining = content_length_ - content_offset_;
    if (data_.size() + content_remaining < data_.capacity() * 2) {
      data_.reserve(data_.size() + content_remaining);
    }
  }

  data_.append(buffer->data(), num_bytes);
  content_offset_ += num_bytes;
  // consumer_task_runner_->PostTask(FROM_HERE,
  // base::Bind((on_write_callback_.Run), std::move(data)));
  return num_bytes;
}

int URLFetcherStringWriter::Finish(int net_error,
                                   net::CompletionOnceCallback callback) {
  return net::OK;
}

}  // namespace loader
}  // namespace cobalt
