// Copyright 2019 The Cobalt Authors. 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/resource_cache.h"

#include <algorithm>
#include <memory>

#include "base/strings/stringprintf.h"
#include "cobalt/base/console_log.h"

namespace cobalt {
namespace loader {

CachedResourceBase::OnLoadedCallbackHandler::OnLoadedCallbackHandler(
    const scoped_refptr<CachedResourceBase>& cached_resource,
    const base::Closure& success_callback,
    const base::Closure& error_callback)
    : cached_resource_(cached_resource),
      success_callback_(success_callback),
      error_callback_(error_callback) {
  DCHECK(cached_resource_);

  if (!success_callback_.is_null()) {
    success_callback_list_iterator_ = cached_resource_->AddCallback(
        kOnLoadingSuccessCallbackType, success_callback_);
    if (cached_resource_->has_resource_func_.Run()) {
      success_callback_.Run();
    }
  }

  if (!error_callback_.is_null()) {
    error_callback_list_iterator_ = cached_resource_->AddCallback(
        kOnLoadingErrorCallbackType, error_callback_);
  }
}

net::LoadTimingInfo
    CachedResourceBase::OnLoadedCallbackHandler::GetLoadTimingInfo() {
  return cached_resource_->GetLoadTimingInfo();
}

CachedResourceBase::OnLoadedCallbackHandler::~OnLoadedCallbackHandler() {
  if (!success_callback_.is_null()) {
    cached_resource_->RemoveCallback(kOnLoadingSuccessCallbackType,
                                     success_callback_list_iterator_);
  }

  if (!error_callback_.is_null()) {
    cached_resource_->RemoveCallback(kOnLoadingErrorCallbackType,
                                     error_callback_list_iterator_);
  }
}

bool CachedResourceBase::IsLoadingComplete() {
  return !loader_ && !retry_timer_;
}

CachedResourceBase::CallbackListIterator CachedResourceBase::AddCallback(
    CallbackType callback_type, const base::Closure& callback) {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);

  CallbackList& callback_list = callback_lists_[callback_type];
  callback_list.push_front(callback);
  return callback_list.begin();
}

void CachedResourceBase::RemoveCallback(CallbackType type,
                                        CallbackListIterator iterator) {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);

  CallbackList& callback_list = callback_lists_[type];
  callback_list.erase(iterator);
}

void CachedResourceBase::RunCallbacks(CallbackType type) {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);

  // To avoid the list getting altered in the callbacks.
  CallbackList callback_list = callback_lists_[type];
  CallbackListIterator callback_iter;
  for (callback_iter = callback_list.begin();
       callback_iter != callback_list.end(); ++callback_iter) {
    callback_iter->Run();
  }
}

void CachedResourceBase::EnableCompletionCallbacks() {
  are_completion_callbacks_enabled_ = true;
  if (!completion_callback_.is_null()) {
    completion_callback_.Run();
  }
}

void CachedResourceBase::StartLoading() {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);
  DCHECK(!loader_);
  DCHECK(!retry_timer_ || !retry_timer_->IsRunning());

  loader_ = start_loading_func_.Run();
}

void CachedResourceBase::ScheduleLoadingRetry() {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);
  DCHECK(!loader_);
  DCHECK(!retry_timer_ || !retry_timer_->IsRunning());

  LOG(WARNING) << "Scheduling loading retry for '" << url_ << "'";
  on_retry_loading_.Run();

  // The delay starts at 1 second and doubles every subsequent retry until the
  // maximum delay of 1024 seconds (~17 minutes) is reached. After this, all
  // additional attempts also wait 1024 seconds.
  const int64 kBaseRetryDelayInMilliseconds = 1000;
  const int kMaxRetryCountShift = 10;
  int64 delay = kBaseRetryDelayInMilliseconds
                << std::min(kMaxRetryCountShift, retry_count_++);

  // The retry timer is lazily created the first time that it is needed.
  if (!retry_timer_) {
    retry_timer_.reset(new base::RetainingOneShotTimer());
  }
  retry_timer_->Start(
      FROM_HERE, base::TimeDelta::FromMilliseconds(delay),
      base::Bind(&CachedResourceBase::StartLoading, base::Unretained(this)));
}

void CachedResourceBase::OnLoadingComplete(
    const base::Optional<std::string>& error) {
  DCHECK_CALLED_ON_VALID_THREAD(cached_resource_thread_checker_);

  load_timing_info_ = loader_->get_load_timing_info();

  // Success
  if (!error) {
    loader_.reset();
    retry_timer_.reset();

    completion_callback_ =
        base::Bind(on_resource_loaded_, kOnLoadingSuccessCallbackType);
    if (are_completion_callbacks_enabled_) {
      completion_callback_.Run();
    }
    // Error
  } else {
    CLOG(WARNING, owner_->debugger_hooks())
        << " Error while loading '" << url_ << "': " << *error;

    if (has_resource_func_.Run()) {
      LOG(WARNING) << "A resource was produced but there was still an error.";
      reset_resource_func_.Run();
    }

    bool should_retry = are_loading_retries_enabled_func_.Run() &&
                        loader_->DidFailFromTransientError();

    loader_.reset();

    if (should_retry) {
      ScheduleLoadingRetry();
    } else {
      retry_timer_.reset();

      completion_callback_ =
          base::Bind(on_resource_loaded_, kOnLoadingErrorCallbackType);
      if (are_completion_callbacks_enabled_) {
        completion_callback_.Run();
      }
    }
  }
}

void ResourceCacheBase::SetCapacity(uint32 capacity) {
  DCHECK_CALLED_ON_VALID_THREAD(resource_cache_thread_checker_);
  cache_capacity_ = capacity;
  memory_capacity_in_bytes_ = capacity;
  ReclaimMemoryAndMaybeProcessPendingCallbacks(cache_capacity_);
}

void ResourceCacheBase::Purge() {
  DCHECK_CALLED_ON_VALID_THREAD(resource_cache_thread_checker_);
  ProcessPendingCallbacks();
  reclaim_memory_func_.Run(0, true);
}

void ResourceCacheBase::ProcessPendingCallbacks() {
  DCHECK_CALLED_ON_VALID_THREAD(resource_cache_thread_checker_);
  process_pending_callback_timer_.Stop();

  // If callbacks are disabled, simply return.
  if (are_callbacks_disabled_) {
    return;
  }

  is_processing_pending_callbacks_ = true;
  while (!pending_callback_map_.empty()) {
    ResourceCallbackInfo& callback_info = pending_callback_map_.front().second;

    // To avoid the last reference of this object getting deleted in the
    // callbacks.
    auto* cached_resource_ptr = callback_info.cached_resource;
    scoped_refptr<CachedResourceBase> holder(cached_resource_ptr);
    callback_info.cached_resource->RunCallbacks(callback_info.callback_type);

    pending_callback_map_.erase(pending_callback_map_.begin());
  }
  is_processing_pending_callbacks_ = false;
  count_pending_callbacks_ = 0;
}

void ResourceCacheBase::DisableCallbacks() {
  DCHECK_CALLED_ON_VALID_THREAD(resource_cache_thread_checker_);
  are_callbacks_disabled_ = true;
}

ResourceCacheBase::ResourceCacheBase(
    const std::string& name, const base::DebuggerHooks& debugger_hooks,
    uint32 cache_capacity, bool are_loading_retries_enabled,
    const ReclaimMemoryFunc& reclaim_memory_func)
    : name_(name),
      debugger_hooks_(debugger_hooks),
      are_loading_retries_enabled_(are_loading_retries_enabled),
      cache_capacity_(cache_capacity),
      reclaim_memory_func_(reclaim_memory_func),
      memory_size_in_bytes_(
          base::StringPrintf("Memory.%s.Size", name_.c_str()), 0,
          "Total number of bytes currently used by the cache."),
      memory_capacity_in_bytes_(
          base::StringPrintf("Memory.%s.Capacity", name_.c_str()),
          cache_capacity_,
          "The capacity, in bytes, of the resource cache.  "
          "Exceeding this results in *unused* resources being "
          "purged."),
      memory_resources_loaded_in_bytes_(
          base::StringPrintf("Memory.%s.Resource.Loaded", name_.c_str()), 0,
          "Combined size in bytes of all resources that have been loaded by "
          "the cache."),
      count_resources_requested_(
          base::StringPrintf("Count.%s.Resource.Requested", name_.c_str()), 0,
          "The total number of resources that have been requested."),
      count_resources_loading_(
          base::StringPrintf("Count.%s.Resource.Loading", name_.c_str()), 0,
          "The number of resources that are currently loading."),
      count_resources_loaded_(
          base::StringPrintf("Count.%s.Resource.Loaded", name_.c_str()), 0,
          "The total number of resources that have been successfully "
          "loaded."),
      count_resources_cached_(
          base::StringPrintf("Count.%s.Resource.Cached", name_.c_str()), 0,
          "The number of resources that are currently in the cache."),
      count_pending_callbacks_(
          base::StringPrintf("Count.%s.PendingCallbacks", name_.c_str()), 0,
          "The number of loading completed resources that have pending "
          "callbacks.") {}

void ResourceCacheBase::NotifyResourceLoadingRetryScheduled(
    CachedResourceBase* cached_resource) {
  DCHECK_CALLED_ON_VALID_THREAD(resource_cache_thread_checker_);
  const std::string& url = cached_resource->url().spec();

  // Remove the resource from those currently loading. It'll be re-added once
  // the retry starts.

  // Remove the resource from its loading set. It should exist in exactly one
  // of the loading sets.
  if (callback_blocking_loading_resource_set_.erase(url)) {
    DCHECK(non_callback_blocking_loading_resource_set_.find(url) ==
           non_callback_blocking_loading_resource_set_.end());
  } else if (!non_callback_blocking_loading_resource_set_.erase(url)) {
    DCHECK(false);
  }

  --count_resources_loading_;

  ProcessPendingCallbacksIfUnblocked();
}

void ResourceCacheBase::ReclaimMemoryAndMaybeProcessPendingCallbacks(
    uint32 bytes_to_reclaim_down_to) {
  reclaim_memory_func_.Run(bytes_to_reclaim_down_to,
                           false /*log_warning_if_over*/);
  // If the current size of the cache is still greater than
  // |bytes_to_reclaim_down_to| after reclaiming memory, then process any
  // pending callbacks and try again. References to the cached resources are
  // potentially being held until the callbacks run, so processing them may
  // enable more memory to be reclaimed.
  if (memory_size_in_bytes_ > bytes_to_reclaim_down_to) {
    ProcessPendingCallbacks();
    reclaim_memory_func_.Run(bytes_to_reclaim_down_to,
                             true /*log_warning_if_over*/);
  }
}

void ResourceCacheBase::ProcessPendingCallbacksIfUnblocked() {
  // If there are no callback blocking resources, then simply process any
  // pending callbacks now; otherwise, start |process_pending_callback_timer_|,
  // which ensures that the callbacks are handled in a timely manner while still
  // allowing them to be batched.
  if (callback_blocking_loading_resource_set_.empty()) {
    ProcessPendingCallbacks();

    // Now that we've processed the callbacks, if there are any non-blocking
    // loading resources, then they're becoming blocking. Simply swap the two
    // sets, rather than copying the contents over.
    if (!non_callback_blocking_loading_resource_set_.empty()) {
      callback_blocking_loading_resource_set_.swap(
          non_callback_blocking_loading_resource_set_);
    }
  } else if (!pending_callback_map_.empty() &&
             !process_pending_callback_timer_.IsRunning()) {
    // The maximum delay for a pending callback is set to 500ms. After that, the
    // callback will be processed regardless of how many callback blocking
    // loading resources remain. This specific value maximizes callback batching
    // on fast networks while also keeping the callback delay on slow networks
    // to a minimum and is based on significant testing.
    const int64 kMaxPendingCallbackDelayInMilliseconds = 500;
    process_pending_callback_timer_.Start(
        FROM_HERE,
        base::TimeDelta::FromMilliseconds(
            kMaxPendingCallbackDelayInMilliseconds),
        base::BindOnce(&ResourceCacheBase::ProcessPendingCallbacks,
                       base::Unretained(this)));
  }
}

}  // namespace loader
}  // namespace cobalt
