// 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 "chrome/browser/password_manager/password_store.h"

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "chrome/browser/password_manager/password_store_consumer.h"
#include "components/autofill/core/common/password_form.h"
#include "content/public/browser/browser_thread.h"

using autofill::PasswordForm;
using content::BrowserThread;
using std::vector;

namespace {

// PasswordStoreConsumer callback requires vector const reference.
void RunConsumerCallbackIfNotCanceled(
    const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb,
    PasswordStoreConsumer* consumer,
    const vector<PasswordForm*>* matched_forms) {
  if (is_canceled_cb.Run()) {
    STLDeleteContainerPointers(matched_forms->begin(), matched_forms->end());
    return;
  }

  // OnGetPasswordStoreResults owns PasswordForms in the vector.
  consumer->OnGetPasswordStoreResults(*matched_forms);
}

void PostConsumerCallback(
    base::TaskRunner* task_runner,
    const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb,
    PasswordStoreConsumer* consumer,
    const base::Time& ignore_logins_cutoff,
    const vector<PasswordForm*>& matched_forms) {
  vector<PasswordForm*>* matched_forms_copy = new vector<PasswordForm*>();
  if (ignore_logins_cutoff.is_null()) {
    *matched_forms_copy = matched_forms;
  } else {
    // Apply |ignore_logins_cutoff| and delete old ones.
    for (size_t i = 0; i < matched_forms.size(); i++) {
      if (matched_forms[i]->date_created < ignore_logins_cutoff)
        delete matched_forms[i];
      else
        matched_forms_copy->push_back(matched_forms[i]);
    }
  }

  task_runner->PostTask(
      FROM_HERE,
      base::Bind(&RunConsumerCallbackIfNotCanceled,
                 is_canceled_cb, consumer, base::Owned(matched_forms_copy)));
}

}  // namespace

PasswordStore::GetLoginsRequest::GetLoginsRequest(
    const GetLoginsCallback& callback)
    : CancelableRequest1<GetLoginsCallback, vector<PasswordForm*> >(callback) {
}

void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() {
  if (!ignore_logins_cutoff_.is_null()) {
    // Count down rather than up since we may be deleting elements.
    // Note that in principle it could be more efficient to copy the whole array
    // since that's worst-case linear time, but we expect that elements will be
    // deleted rarely and lists will be small, so this avoids the copies.
    for (size_t i = value.size(); i > 0; --i) {
      if (value[i - 1]->date_created < ignore_logins_cutoff_) {
        delete value[i - 1];
        value.erase(value.begin() + (i - 1));
      }
    }
  }
}

PasswordStore::GetLoginsRequest::~GetLoginsRequest() {
  if (canceled()) {
    STLDeleteElements(&value);
  }
}

PasswordStore::PasswordStore() {
}

bool PasswordStore::Init() {
  ReportMetrics();
  return true;
}

void PasswordStore::AddLogin(const PasswordForm& form) {
  ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this,
      base::Closure(base::Bind(&PasswordStore::AddLoginImpl, this, form))));
}

void PasswordStore::UpdateLogin(const PasswordForm& form) {
  ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this,
      base::Closure(base::Bind(&PasswordStore::UpdateLoginImpl, this, form))));
}

void PasswordStore::RemoveLogin(const PasswordForm& form) {
  ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this,
      base::Closure(base::Bind(&PasswordStore::RemoveLoginImpl, this, form))));
}

void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin,
                                               const base::Time& delete_end) {
  ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this,
      base::Closure(
          base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, this,
                     delete_begin, delete_end))));
}

CancelableTaskTracker::TaskId PasswordStore::GetLogins(
    const PasswordForm& form,
    PasswordStoreConsumer* consumer) {
  // Per http://crbug.com/121738, we deliberately ignore saved logins for
  // http*://www.google.com/ that were stored prior to 2012. (Google now uses
  // https://accounts.google.com/ for all login forms, so these should be
  // unused.) We don't delete them just yet, and they'll still be visible in the
  // password manager, but we won't use them to autofill any forms. This is a
  // security feature to help minimize damage that can be done by XSS attacks.
  // TODO(mdm): actually delete them at some point, say M24 or so.
  base::Time ignore_logins_cutoff;  // the null time
  if (form.scheme == PasswordForm::SCHEME_HTML &&
      (form.signon_realm == "http://www.google.com" ||
       form.signon_realm == "http://www.google.com/" ||
       form.signon_realm == "https://www.google.com" ||
       form.signon_realm == "https://www.google.com/")) {
    static const base::Time::Exploded exploded_cutoff =
        { 2012, 1, 0, 1, 0, 0, 0, 0 };  // 00:00 Jan 1 2012
    ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff);
  }

  CancelableTaskTracker::IsCanceledCallback is_canceled_cb;
  CancelableTaskTracker::TaskId id =
      consumer->cancelable_task_tracker()->NewTrackedTaskId(&is_canceled_cb);

  ConsumerCallbackRunner callback_runner =
      base::Bind(&PostConsumerCallback,
                 base::MessageLoopProxy::current(),
                 is_canceled_cb,
                 consumer,
                 ignore_logins_cutoff);
  ScheduleTask(
      base::Bind(&PasswordStore::GetLoginsImpl, this, form, callback_runner));
  return id;
}

CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins(
    PasswordStoreConsumer* consumer) {
  return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
}

CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins(
    PasswordStoreConsumer* consumer) {
  return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer);
}

void PasswordStore::ReportMetrics() {
  ScheduleTask(base::Bind(&PasswordStore::ReportMetricsImpl, this));
}

void PasswordStore::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void PasswordStore::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

PasswordStore::~PasswordStore() {}

PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest(
    const GetLoginsCallback& callback) {
  return new GetLoginsRequest(callback);
}

bool PasswordStore::ScheduleTask(const base::Closure& task) {
  return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task);
}

void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) {
  request->ApplyIgnoreLoginsCutoff();
  request->ForwardResult(request->handle(), request->value);
}

void PasswordStore::LogStatsForBulkDeletion(int num_deletions) {
  UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete",
                       num_deletions);
}

template<typename BackendFunc>
CancelableRequestProvider::Handle PasswordStore::Schedule(
    BackendFunc func,
    PasswordStoreConsumer* consumer) {
  scoped_refptr<GetLoginsRequest> request(
      NewGetLoginsRequest(
          base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone,
                     base::Unretained(consumer))));
  AddRequest(request.get(), consumer->cancelable_consumer());
  ScheduleTask(base::Bind(func, this, request));
  return request->handle();
}

template<typename BackendFunc>
CancelableRequestProvider::Handle PasswordStore::Schedule(
    BackendFunc func,
    PasswordStoreConsumer* consumer,
    const PasswordForm& form,
    const base::Time& ignore_logins_cutoff) {
  scoped_refptr<GetLoginsRequest> request(
      NewGetLoginsRequest(
          base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone,
                     base::Unretained(consumer))));
  request->set_ignore_logins_cutoff(ignore_logins_cutoff);
  AddRequest(request.get(), consumer->cancelable_consumer());
  ScheduleTask(base::Bind(func, this, request, form));
  return request->handle();
}

void PasswordStore::WrapModificationTask(base::Closure task) {
#if !defined(OS_MACOSX)
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
#endif  // !defined(OS_MACOSX)
  task.Run();
  PostNotifyLoginsChanged();
}

void PasswordStore::PostNotifyLoginsChanged() {
#if !defined(OS_MACOSX)
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
#endif  // !defined(OS_MACOSX)
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&PasswordStore::NotifyLoginsChanged, this));
}

void PasswordStore::NotifyLoginsChanged() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged());
}
