// Copyright (c) 2012 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 "content/browser/appcache/appcache_group.h"

#include <algorithm>

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_service_impl.h"
#include "content/browser/appcache/appcache_storage.h"
#include "content/browser/appcache/appcache_update_job.h"

namespace content {

class AppCacheGroup;

// Use this helper class because we cannot make AppCacheGroup a derived class
// of AppCacheHost::Observer as it would create a circular dependency between
// AppCacheHost and AppCacheGroup.
class AppCacheGroup::HostObserver : public AppCacheHost::Observer {
 public:
  explicit HostObserver(AppCacheGroup* group) : group_(group) {}

  // Methods for AppCacheHost::Observer.
  virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE {}  // N/A
  virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE {
    group_->HostDestructionImminent(host);
  }
 private:
  AppCacheGroup* group_;
};

AppCacheGroup::AppCacheGroup(AppCacheStorage* storage,
                             const GURL& manifest_url,
                             int64 group_id)
    : group_id_(group_id),
      manifest_url_(manifest_url),
      update_status_(IDLE),
      is_obsolete_(false),
      is_being_deleted_(false),
      newest_complete_cache_(NULL),
      update_job_(NULL),
      storage_(storage),
      is_in_dtor_(false) {
  storage_->working_set()->AddGroup(this);
  host_observer_.reset(new HostObserver(this));
}

AppCacheGroup::~AppCacheGroup() {
  DCHECK(old_caches_.empty());
  DCHECK(!newest_complete_cache_);
  DCHECK(restart_update_task_.IsCancelled());
  DCHECK(queued_updates_.empty());

  is_in_dtor_ = true;

  if (update_job_)
    delete update_job_;
  DCHECK_EQ(IDLE, update_status_);

  storage_->working_set()->RemoveGroup(this);
  storage_->DeleteResponses(manifest_url_, newly_deletable_response_ids_);
}

void AppCacheGroup::AddUpdateObserver(UpdateObserver* observer) {
  // If observer being added is a host that has been queued for later update,
  // add observer to a different observer list.
  AppCacheHost* host = static_cast<AppCacheHost*>(observer);
  if (queued_updates_.find(host) != queued_updates_.end())
    queued_observers_.AddObserver(observer);
  else
    observers_.AddObserver(observer);
}

void AppCacheGroup::RemoveUpdateObserver(UpdateObserver* observer) {
  observers_.RemoveObserver(observer);
  queued_observers_.RemoveObserver(observer);
}

void AppCacheGroup::AddCache(AppCache* complete_cache) {
  DCHECK(complete_cache->is_complete());
  complete_cache->set_owning_group(this);

  if (!newest_complete_cache_) {
    newest_complete_cache_ = complete_cache;
    return;
  }

  if (complete_cache->IsNewerThan(newest_complete_cache_)) {
    old_caches_.push_back(newest_complete_cache_);
    newest_complete_cache_ = complete_cache;

    // Update hosts of older caches to add a reference to the newest cache.
    for (Caches::iterator it = old_caches_.begin();
         it != old_caches_.end(); ++it) {
      AppCache::AppCacheHosts& hosts = (*it)->associated_hosts();
      for (AppCache::AppCacheHosts::iterator host_it = hosts.begin();
           host_it != hosts.end(); ++host_it) {
        (*host_it)->SetSwappableCache(this);
      }
    }
  } else {
    old_caches_.push_back(complete_cache);
  }
}

void AppCacheGroup::RemoveCache(AppCache* cache) {
  DCHECK(cache->associated_hosts().empty());
  if (cache == newest_complete_cache_) {
    AppCache* tmp_cache = newest_complete_cache_;
    newest_complete_cache_ = NULL;
    tmp_cache->set_owning_group(NULL);  // may cause this group to be deleted
  } else {
    scoped_refptr<AppCacheGroup> protect(this);

    Caches::iterator it =
        std::find(old_caches_.begin(), old_caches_.end(), cache);
    if (it != old_caches_.end()) {
      AppCache* tmp_cache = *it;
      old_caches_.erase(it);
      tmp_cache->set_owning_group(NULL);  // may cause group to be released
    }

    if (!is_obsolete() && old_caches_.empty() &&
        !newly_deletable_response_ids_.empty()) {
      storage_->DeleteResponses(manifest_url_, newly_deletable_response_ids_);
      newly_deletable_response_ids_.clear();
    }
  }
}

void AppCacheGroup::AddNewlyDeletableResponseIds(
    std::vector<int64>* response_ids) {
  if (is_being_deleted() || (!is_obsolete() && old_caches_.empty())) {
    storage_->DeleteResponses(manifest_url_, *response_ids);
    response_ids->clear();
    return;
  }

  if (newly_deletable_response_ids_.empty()) {
    newly_deletable_response_ids_.swap(*response_ids);
    return;
  }
  newly_deletable_response_ids_.insert(
      newly_deletable_response_ids_.end(),
      response_ids->begin(), response_ids->end());
  response_ids->clear();
}

void AppCacheGroup::StartUpdateWithNewMasterEntry(
    AppCacheHost* host, const GURL& new_master_resource) {
  DCHECK(!is_obsolete() && !is_being_deleted());
  if (is_in_dtor_)
    return;

  if (!update_job_)
    update_job_ = new AppCacheUpdateJob(storage_->service(), this);

  update_job_->StartUpdate(host, new_master_resource);

  // Run queued update immediately as an update has been started manually.
  if (!restart_update_task_.IsCancelled()) {
    restart_update_task_.Cancel();
    RunQueuedUpdates();
  }
}

void AppCacheGroup::CancelUpdate() {
  if (update_job_) {
    delete update_job_;
    DCHECK(!update_job_);
    DCHECK_EQ(IDLE, update_status_);
  }
}

void AppCacheGroup::QueueUpdate(AppCacheHost* host,
                                const GURL& new_master_resource) {
  DCHECK(update_job_ && host && !new_master_resource.is_empty());
  queued_updates_.insert(QueuedUpdates::value_type(host, new_master_resource));

  // Need to know when host is destroyed.
  host->AddObserver(host_observer_.get());

  // If host is already observing for updates, move host to queued observers
  // list so that host is not notified when the current update completes.
  if (FindObserver(host, observers_)) {
    observers_.RemoveObserver(host);
    queued_observers_.AddObserver(host);
  }
}

void AppCacheGroup::RunQueuedUpdates() {
  if (!restart_update_task_.IsCancelled())
    restart_update_task_.Cancel();

  if (queued_updates_.empty())
    return;

  QueuedUpdates updates_to_run;
  queued_updates_.swap(updates_to_run);
  DCHECK(queued_updates_.empty());

  for (QueuedUpdates::iterator it = updates_to_run.begin();
       it != updates_to_run.end(); ++it) {
    AppCacheHost* host = it->first;
    host->RemoveObserver(host_observer_.get());
    if (FindObserver(host, queued_observers_)) {
      queued_observers_.RemoveObserver(host);
      observers_.AddObserver(host);
    }

    if (!is_obsolete() && !is_being_deleted())
      StartUpdateWithNewMasterEntry(host, it->second);
  }
}

bool AppCacheGroup::FindObserver(UpdateObserver* find_me,
    const ObserverList<UpdateObserver>& observer_list) {
  return observer_list.HasObserver(find_me);
}

void AppCacheGroup::ScheduleUpdateRestart(int delay_ms) {
  DCHECK(restart_update_task_.IsCancelled());
  restart_update_task_.Reset(
      base::Bind(&AppCacheGroup::RunQueuedUpdates, this));
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      restart_update_task_.callback(),
      base::TimeDelta::FromMilliseconds(delay_ms));
}

void AppCacheGroup::HostDestructionImminent(AppCacheHost* host) {
  queued_updates_.erase(host);
  if (queued_updates_.empty() && !restart_update_task_.IsCancelled())
    restart_update_task_.Cancel();
}

void AppCacheGroup::SetUpdateAppCacheStatus(UpdateAppCacheStatus status) {
  if (status == update_status_)
    return;

  update_status_ = status;

  if (status != IDLE) {
    DCHECK(update_job_);
  } else {
    update_job_ = NULL;

    // Observers may release us in these callbacks, so we protect against
    // deletion by adding an extra ref in this scope (but only if we're not
    // in our destructor).
    scoped_refptr<AppCacheGroup> protect(is_in_dtor_ ? NULL : this);
    FOR_EACH_OBSERVER(UpdateObserver, observers_, OnUpdateComplete(this));
    if (!queued_updates_.empty())
      ScheduleUpdateRestart(kUpdateRestartDelayMs);
  }
}

}  // namespace content
