// 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"

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_);
  }
}

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
  // maxiumum 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_);

  // 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 {
    LOG(WARNING) << " 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, uint32 cache_capacity,
    bool are_loading_retries_enabled,
    const ReclaimMemoryFunc& reclaim_memory_func)
    : name_(name),
      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
