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

// DownloadHistory manages persisting DownloadItems to the history service by
// observing a single DownloadManager and all its DownloadItems using an
// AllDownloadItemNotifier.
//
// DownloadHistory decides whether and when to add items to, remove items from,
// and update items in the database. DownloadHistory uses DownloadHistoryData to
// store per-DownloadItem data such as whether the item is persisted or being
// persisted, and the last history::DownloadRow that was passed to the database.
// When the DownloadManager and its delegate (ChromeDownloadManagerDelegate) are
// initialized, DownloadHistory is created and queries the HistoryService. When
// the HistoryService calls back from QueryDownloads() to QueryCallback(),
// DownloadHistory uses DownloadManager::CreateDownloadItem() to inform
// DownloadManager of these persisted DownloadItems. CreateDownloadItem()
// internally calls OnDownloadCreated(), which normally adds items to the
// database, so QueryCallback() uses |loading_id_| to disable adding these items
// to the database.  If a download is removed via OnDownloadRemoved() while the
// item is still being added to the database, DownloadHistory uses
// |removed_while_adding_| to remember to remove the item when its ItemAdded()
// callback is called.  All callbacks are bound with a weak pointer to
// DownloadHistory to prevent use-after-free bugs.
// ChromeDownloadManagerDelegate owns DownloadHistory, and deletes it in
// Shutdown(), which is called by DownloadManagerImpl::Shutdown() after all
// DownloadItems are destroyed.

#include "chrome/browser/download/download_history.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/history/download_database.h"
#include "chrome/browser/history/download_row.h"
#include "chrome/browser/history/history_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"

#if defined(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#endif

namespace {

// Per-DownloadItem data. This information does not belong inside DownloadItem,
// and keeping maps in DownloadHistory from DownloadItem to this information is
// error-prone and complicated. Unfortunately, DownloadHistory::removing_*_ and
// removed_while_adding_ cannot be moved into this class partly because
// DownloadHistoryData is destroyed when DownloadItems are destroyed, and we
// have no control over when DownloadItems are destroyed.
class DownloadHistoryData : public base::SupportsUserData::Data {
 public:
  enum PersistenceState {
    NOT_PERSISTED,
    PERSISTING,
    PERSISTED,
  };

  static DownloadHistoryData* Get(content::DownloadItem* item) {
    base::SupportsUserData::Data* data = item->GetUserData(kKey);
    return (data == NULL) ? NULL :
      static_cast<DownloadHistoryData*>(data);
  }

  static const DownloadHistoryData* Get(const content::DownloadItem* item) {
    const base::SupportsUserData::Data* data = item->GetUserData(kKey);
    return (data == NULL) ? NULL
                          : static_cast<const DownloadHistoryData*>(data);
  }

  explicit DownloadHistoryData(content::DownloadItem* item)
      : state_(NOT_PERSISTED),
        was_restored_from_history_(false) {
    item->SetUserData(kKey, this);
  }

  virtual ~DownloadHistoryData() {
  }

  PersistenceState state() const { return state_; }
  void SetState(PersistenceState s) { state_ = s; }

  bool was_restored_from_history() const { return was_restored_from_history_; }
  void set_was_restored_from_history(bool value) {
    was_restored_from_history_ = value;
  }

  // This allows DownloadHistory::OnDownloadUpdated() to see what changed in a
  // DownloadItem if anything, in order to prevent writing to the database
  // unnecessarily.  It is nullified when the item is no longer in progress in
  // order to save memory.
  history::DownloadRow* info() { return info_.get(); }
  void set_info(const history::DownloadRow& i) {
    info_.reset(new history::DownloadRow(i));
  }
  void clear_info() {
    info_.reset();
  }

 private:
  static const char kKey[];

  PersistenceState state_;
  scoped_ptr<history::DownloadRow> info_;
  bool was_restored_from_history_;

  DISALLOW_COPY_AND_ASSIGN(DownloadHistoryData);
};

const char DownloadHistoryData::kKey[] =
  "DownloadItem DownloadHistoryData";

history::DownloadRow GetDownloadRow(
    content::DownloadItem* item) {
  std::string by_ext_id, by_ext_name;
#if defined(ENABLE_EXTENSIONS)
  extensions::DownloadedByExtension* by_ext =
      extensions::DownloadedByExtension::Get(item);
  if (by_ext) {
    by_ext_id = by_ext->id();
    by_ext_name = by_ext->name();
  }
#endif

  return history::DownloadRow(
      item->GetFullPath(),
      item->GetTargetFilePath(),
      item->GetUrlChain(),
      item->GetReferrerUrl(),
      item->GetMimeType(),
      item->GetOriginalMimeType(),
      item->GetStartTime(),
      item->GetEndTime(),
      item->GetETag(),
      item->GetLastModifiedTime(),
      item->GetReceivedBytes(),
      item->GetTotalBytes(),
      item->GetState(),
      item->GetDangerType(),
      item->GetLastReason(),
      item->GetId(),
      item->GetOpened(),
      by_ext_id,
      by_ext_name);
}

bool ShouldUpdateHistory(const history::DownloadRow* previous,
                         const history::DownloadRow& current) {
  // Ignore url, referrer, mime_type, original_mime_type, start_time,
  // id, db_handle, which don't change.
  return ((previous == NULL) ||
          (previous->current_path != current.current_path) ||
          (previous->target_path != current.target_path) ||
          (previous->end_time != current.end_time) ||
          (previous->received_bytes != current.received_bytes) ||
          (previous->total_bytes != current.total_bytes) ||
          (previous->etag != current.etag) ||
          (previous->last_modified != current.last_modified) ||
          (previous->state != current.state) ||
          (previous->danger_type != current.danger_type) ||
          (previous->interrupt_reason != current.interrupt_reason) ||
          (previous->opened != current.opened) ||
          (previous->by_ext_id != current.by_ext_id) ||
          (previous->by_ext_name != current.by_ext_name));
}

typedef std::vector<history::DownloadRow> InfoVector;

}  // anonymous namespace

DownloadHistory::HistoryAdapter::HistoryAdapter(HistoryService* history)
  : history_(history) {
}
DownloadHistory::HistoryAdapter::~HistoryAdapter() {}

void DownloadHistory::HistoryAdapter::QueryDownloads(
    const HistoryService::DownloadQueryCallback& callback) {
  history_->QueryDownloads(callback);
}

void DownloadHistory::HistoryAdapter::CreateDownload(
    const history::DownloadRow& info,
    const HistoryService::DownloadCreateCallback& callback) {
  history_->CreateDownload(info, callback);
}

void DownloadHistory::HistoryAdapter::UpdateDownload(
    const history::DownloadRow& data) {
  history_->UpdateDownload(data);
}

void DownloadHistory::HistoryAdapter::RemoveDownloads(
    const std::set<uint32>& ids) {
  history_->RemoveDownloads(ids);
}

DownloadHistory::Observer::Observer() {}
DownloadHistory::Observer::~Observer() {}

// static
bool DownloadHistory::IsPersisted(const content::DownloadItem* item) {
  const DownloadHistoryData* data = DownloadHistoryData::Get(item);
  return data && (data->state() == DownloadHistoryData::PERSISTED);
}

DownloadHistory::DownloadHistory(content::DownloadManager* manager,
                                 scoped_ptr<HistoryAdapter> history)
  : notifier_(manager, this),
    history_(history.Pass()),
    loading_id_(content::DownloadItem::kInvalidId),
    history_size_(0),
    weak_ptr_factory_(this) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  content::DownloadManager::DownloadVector items;
  notifier_.GetManager()->GetAllDownloads(&items);
  for (content::DownloadManager::DownloadVector::const_iterator
       it = items.begin(); it != items.end(); ++it) {
    OnDownloadCreated(notifier_.GetManager(), *it);
  }
  history_->QueryDownloads(base::Bind(
      &DownloadHistory::QueryCallback, weak_ptr_factory_.GetWeakPtr()));
}

DownloadHistory::~DownloadHistory() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadHistoryDestroyed());
  observers_.Clear();
}

void DownloadHistory::AddObserver(DownloadHistory::Observer* observer) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  observers_.AddObserver(observer);
}

void DownloadHistory::RemoveObserver(DownloadHistory::Observer* observer) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  observers_.RemoveObserver(observer);
}

bool DownloadHistory::WasRestoredFromHistory(
    const content::DownloadItem* download) const {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  const DownloadHistoryData* data = DownloadHistoryData::Get(download);

  // The OnDownloadCreated handler sets the was_restored_from_history flag when
  // resetting the loading_id_. So one of the two conditions below will hold for
  // a download restored from history even if the caller of this method is
  // racing with our OnDownloadCreated handler.
  return (data && data->was_restored_from_history()) ||
         download->GetId() == loading_id_;
}

void DownloadHistory::QueryCallback(scoped_ptr<InfoVector> infos) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  // ManagerGoingDown() may have happened before the history loaded.
  if (!notifier_.GetManager())
    return;
  for (InfoVector::const_iterator it = infos->begin();
       it != infos->end(); ++it) {
    loading_id_ = it->id;
    content::DownloadItem* item = notifier_.GetManager()->CreateDownloadItem(
        loading_id_,
        it->current_path,
        it->target_path,
        it->url_chain,
        it->referrer_url,
        it->mime_type,
        it->original_mime_type,
        it->start_time,
        it->end_time,
        it->etag,
        it->last_modified,
        it->received_bytes,
        it->total_bytes,
        it->state,
        it->danger_type,
        it->interrupt_reason,
        it->opened);
#if defined(ENABLE_EXTENSIONS)
    if (!it->by_ext_id.empty() && !it->by_ext_name.empty()) {
      new extensions::DownloadedByExtension(
          item, it->by_ext_id, it->by_ext_name);
      item->UpdateObservers();
    }
#endif
    DCHECK_EQ(DownloadHistoryData::PERSISTED,
              DownloadHistoryData::Get(item)->state());
    ++history_size_;
  }
  notifier_.GetManager()->CheckForHistoryFilesRemoval();
}

void DownloadHistory::MaybeAddToHistory(content::DownloadItem* item) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  uint32 download_id = item->GetId();
  DownloadHistoryData* data = DownloadHistoryData::Get(item);
  bool removing = removing_ids_.find(download_id) != removing_ids_.end();

  // TODO(benjhayden): Remove IsTemporary().
  if (download_crx_util::IsExtensionDownload(*item) ||
      item->IsTemporary() ||
      (data->state() != DownloadHistoryData::NOT_PERSISTED) ||
      removing)
    return;

  data->SetState(DownloadHistoryData::PERSISTING);
  if (data->info() == NULL) {
    // Keep the info here regardless of whether the item is in progress so that,
    // when ItemAdded() calls OnDownloadUpdated(), it can decide whether to
    // Update the db and/or clear the info.
    data->set_info(GetDownloadRow(item));
  }

  history_->CreateDownload(*data->info(), base::Bind(
      &DownloadHistory::ItemAdded, weak_ptr_factory_.GetWeakPtr(),
      download_id));
  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadStored(
      item, *data->info()));
}

void DownloadHistory::ItemAdded(uint32 download_id, bool success) {
  if (removed_while_adding_.find(download_id) !=
      removed_while_adding_.end()) {
    removed_while_adding_.erase(download_id);
    if (success)
      ScheduleRemoveDownload(download_id);
    return;
  }

  if (!notifier_.GetManager())
    return;

  content::DownloadItem* item = notifier_.GetManager()->GetDownload(
      download_id);
  if (!item) {
    // This item will have called OnDownloadDestroyed().  If the item should
    // have been removed from history, then it would have also called
    // OnDownloadRemoved(), which would have put |download_id| in
    // removed_while_adding_, handled above.
    return;
  }

  DownloadHistoryData* data = DownloadHistoryData::Get(item);

  // The sql INSERT statement failed. Avoid an infinite loop: don't
  // automatically retry. Retry adding the next time the item is updated by
  // resetting the state to NOT_PERSISTED.
  if (!success) {
    DVLOG(20) << __FUNCTION__ << " INSERT failed id=" << download_id;
    data->SetState(DownloadHistoryData::NOT_PERSISTED);
    return;
  }
  data->SetState(DownloadHistoryData::PERSISTED);

  UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize2",
                              history_size_,
                              0/*min*/,
                              (1 << 23)/*max*/,
                              (1 << 7)/*num_buckets*/);
  ++history_size_;

  // In case the item changed or became temporary while it was being added.
  // Don't just update all of the item's observers because we're the only
  // observer that can also see data->state(), which is the only thing that
  // ItemAdded() changed.
  OnDownloadUpdated(notifier_.GetManager(), item);
}

void DownloadHistory::OnDownloadCreated(
    content::DownloadManager* manager, content::DownloadItem* item) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  // All downloads should pass through OnDownloadCreated exactly once.
  CHECK(!DownloadHistoryData::Get(item));
  DownloadHistoryData* data = new DownloadHistoryData(item);
  if (item->GetId() == loading_id_) {
    data->SetState(DownloadHistoryData::PERSISTED);
    data->set_was_restored_from_history(true);
    loading_id_ = content::DownloadItem::kInvalidId;
  }
  if (item->GetState() == content::DownloadItem::IN_PROGRESS) {
    data->set_info(GetDownloadRow(item));
  }
  MaybeAddToHistory(item);
}

void DownloadHistory::OnDownloadUpdated(
    content::DownloadManager* manager, content::DownloadItem* item) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  DownloadHistoryData* data = DownloadHistoryData::Get(item);
  if (data->state() == DownloadHistoryData::NOT_PERSISTED) {
    MaybeAddToHistory(item);
    return;
  }
  if (item->IsTemporary()) {
    OnDownloadRemoved(notifier_.GetManager(), item);
    return;
  }

  history::DownloadRow current_info(GetDownloadRow(item));
  bool should_update = ShouldUpdateHistory(data->info(), current_info);
  UMA_HISTOGRAM_ENUMERATION("Download.HistoryPropagatedUpdate",
                            should_update, 2);
  if (should_update) {
    history_->UpdateDownload(current_info);
    FOR_EACH_OBSERVER(Observer, observers_, OnDownloadStored(
        item, current_info));
  }
  if (item->GetState() == content::DownloadItem::IN_PROGRESS) {
    data->set_info(current_info);
  } else {
    data->clear_info();
  }
}

void DownloadHistory::OnDownloadOpened(
    content::DownloadManager* manager, content::DownloadItem* item) {
  OnDownloadUpdated(manager, item);
}

void DownloadHistory::OnDownloadRemoved(
    content::DownloadManager* manager, content::DownloadItem* item) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  DownloadHistoryData* data = DownloadHistoryData::Get(item);
  if (data->state() != DownloadHistoryData::PERSISTED) {
    if (data->state() == DownloadHistoryData::PERSISTING) {
      // ScheduleRemoveDownload will be called when history_ calls ItemAdded().
      removed_while_adding_.insert(item->GetId());
    }
    return;
  }
  ScheduleRemoveDownload(item->GetId());
  // This is important: another OnDownloadRemoved() handler could do something
  // that synchronously fires an OnDownloadUpdated().
  data->SetState(DownloadHistoryData::NOT_PERSISTED);
  // ItemAdded increments history_size_ only if the item wasn't
  // removed_while_adding_, so the next line does not belong in
  // ScheduleRemoveDownload().
  --history_size_;
}

void DownloadHistory::ScheduleRemoveDownload(uint32 download_id) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  // For database efficiency, batch removals together if they happen all at
  // once.
  if (removing_ids_.empty()) {
    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
        base::Bind(&DownloadHistory::RemoveDownloadsBatch,
                   weak_ptr_factory_.GetWeakPtr()));
  }
  removing_ids_.insert(download_id);
}

void DownloadHistory::RemoveDownloadsBatch() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  IdSet remove_ids;
  removing_ids_.swap(remove_ids);
  history_->RemoveDownloads(remove_ids);
  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadsRemoved(remove_ids));
}
