// Copyright (c) 2011 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/webdata/autofill_table.h"

#include <algorithm>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "app/sql/statement.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/time.h"
#include "base/tuple.h"
#include "chrome/browser/autofill/autofill_country.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/credit_card.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/password_manager/encryptor.h"
#include "chrome/browser/webdata/autofill_change.h"
#include "chrome/common/guid.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/glue/form_field.h"

using base::Time;
using webkit_glue::FormField;

namespace {

// Constants for the |autofill_profile_phones| |type| column.
enum AutofillPhoneType {
  kAutofillPhoneNumber = 0,
  kAutofillFaxNumber = 1
};

typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList;

// TODO(dhollowa): Find a common place for this.  It is duplicated in
// personal_data_manager.cc.
template<typename T>
T* address_of(T& v) {
  return &v;
}

// The maximum length allowed for form data.
const size_t kMaxDataLength = 1024;

string16 LimitDataSize(const string16& data) {
  if (data.size() > kMaxDataLength)
    return data.substr(0, kMaxDataLength);

  return data;
}

void BindAutofillProfileToStatement(const AutofillProfile& profile,
                                    sql::Statement* s) {
  DCHECK(guid::IsValidGUID(profile.guid()));
  s->BindString(0, profile.guid());

  string16 text = profile.GetInfo(COMPANY_NAME);
  s->BindString16(1, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_LINE1);
  s->BindString16(2, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_LINE2);
  s->BindString16(3, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_CITY);
  s->BindString16(4, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_STATE);
  s->BindString16(5, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_ZIP);
  s->BindString16(6, LimitDataSize(text));
  text = profile.GetInfo(ADDRESS_HOME_COUNTRY);
  s->BindString16(7, LimitDataSize(text));
  std::string country_code = profile.CountryCode();
  s->BindString(8, country_code);
  s->BindInt64(9, Time::Now().ToTimeT());
}

AutofillProfile* AutofillProfileFromStatement(const sql::Statement& s) {
  AutofillProfile* profile = new AutofillProfile;
  profile->set_guid(s.ColumnString(0));
  DCHECK(guid::IsValidGUID(profile->guid()));

  profile->SetInfo(COMPANY_NAME, s.ColumnString16(1));
  profile->SetInfo(ADDRESS_HOME_LINE1, s.ColumnString16(2));
  profile->SetInfo(ADDRESS_HOME_LINE2, s.ColumnString16(3));
  profile->SetInfo(ADDRESS_HOME_CITY, s.ColumnString16(4));
  profile->SetInfo(ADDRESS_HOME_STATE, s.ColumnString16(5));
  profile->SetInfo(ADDRESS_HOME_ZIP, s.ColumnString16(6));
  // Intentionally skip column 7, which stores the localized country name.
  profile->SetCountryCode(s.ColumnString(8));
  // Intentionally skip column 9, which stores the profile's modification date.

  return profile;
}

void BindCreditCardToStatement(const CreditCard& credit_card,
                               sql::Statement* s) {
  DCHECK(guid::IsValidGUID(credit_card.guid()));
  s->BindString(0, credit_card.guid());

  string16 text = credit_card.GetInfo(CREDIT_CARD_NAME);
  s->BindString16(1, LimitDataSize(text));
  text = credit_card.GetInfo(CREDIT_CARD_EXP_MONTH);
  s->BindString16(2, LimitDataSize(text));
  text = credit_card.GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR);
  s->BindString16(3, LimitDataSize(text));
  text = credit_card.GetInfo(CREDIT_CARD_NUMBER);
  std::string encrypted_data;
  Encryptor::EncryptString16(text, &encrypted_data);
  s->BindBlob(4, encrypted_data.data(),
              static_cast<int>(encrypted_data.length()));
  s->BindInt64(5, Time::Now().ToTimeT());
}

CreditCard* CreditCardFromStatement(const sql::Statement& s) {
  CreditCard* credit_card = new CreditCard;

  credit_card->set_guid(s.ColumnString(0));
  DCHECK(guid::IsValidGUID(credit_card->guid()));

  credit_card->SetInfo(CREDIT_CARD_NAME, s.ColumnString16(1));
  credit_card->SetInfo(CREDIT_CARD_EXP_MONTH,
                       s.ColumnString16(2));
  credit_card->SetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
                       s.ColumnString16(3));
  int encrypted_number_len = s.ColumnByteLength(4);
  string16 credit_card_number;
  if (encrypted_number_len) {
    std::string encrypted_number;
    encrypted_number.resize(encrypted_number_len);
    memcpy(&encrypted_number[0], s.ColumnBlob(4), encrypted_number_len);
    Encryptor::DecryptString16(encrypted_number, &credit_card_number);
  }
  credit_card->SetInfo(CREDIT_CARD_NUMBER, credit_card_number);
  // Intentionally skip column 5, which stores the modification date.

  return credit_card;
}

bool AddAutofillProfileNamesToProfile(sql::Connection* db,
                                      AutofillProfile* profile) {
  sql::Statement s(db->GetUniqueStatement(
      "SELECT guid, first_name, middle_name, last_name "
      "FROM autofill_profile_names "
      "WHERE guid=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }
  s.BindString(0, profile->guid());

  std::vector<string16> first_names;
  std::vector<string16> middle_names;
  std::vector<string16> last_names;
  while (s.Step()) {
    DCHECK_EQ(profile->guid(), s.ColumnString(0));
    first_names.push_back(s.ColumnString16(1));
    middle_names.push_back(s.ColumnString16(2));
    last_names.push_back(s.ColumnString16(3));
  }
  profile->SetMultiInfo(NAME_FIRST, first_names);
  profile->SetMultiInfo(NAME_MIDDLE, middle_names);
  profile->SetMultiInfo(NAME_LAST, last_names);
  return true;
}

bool AddAutofillProfileEmailsToProfile(sql::Connection* db,
                                       AutofillProfile* profile) {
  sql::Statement s(db->GetUniqueStatement(
      "SELECT guid, email "
      "FROM autofill_profile_emails "
      "WHERE guid=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }
  s.BindString(0, profile->guid());

  std::vector<string16> emails;
  while (s.Step()) {
    DCHECK_EQ(profile->guid(), s.ColumnString(0));
    emails.push_back(s.ColumnString16(1));
  }
  profile->SetMultiInfo(EMAIL_ADDRESS, emails);
  return true;
}

bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
                                       AutofillProfile* profile) {
  sql::Statement s(db->GetUniqueStatement(
      "SELECT guid, type, number "
      "FROM autofill_profile_phones "
      "WHERE guid=? AND type=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }
  s.BindString(0, profile->guid());
  s.BindInt(1, kAutofillPhoneNumber);

  std::vector<string16> numbers;
  while (s.Step()) {
    DCHECK_EQ(profile->guid(), s.ColumnString(0));
    numbers.push_back(s.ColumnString16(2));
  }
  profile->SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, numbers);
  return true;
}

bool AddAutofillProfileFaxesToProfile(sql::Connection* db,
                                      AutofillProfile* profile) {
  sql::Statement s(db->GetUniqueStatement(
      "SELECT guid, type, number "
      "FROM autofill_profile_phones "
      "WHERE guid=? AND type=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }
  s.BindString(0, profile->guid());
  s.BindInt(1, kAutofillFaxNumber);

  std::vector<string16> numbers;
  while (s.Step()) {
    DCHECK_EQ(profile->guid(), s.ColumnString(0));
    numbers.push_back(s.ColumnString16(2));
  }
  profile->SetMultiInfo(PHONE_FAX_WHOLE_NUMBER, numbers);
  return true;
}


bool AddAutofillProfileNames(const AutofillProfile& profile,
                             sql::Connection* db) {
  std::vector<string16> first_names;
  profile.GetMultiInfo(NAME_FIRST, &first_names);
  std::vector<string16> middle_names;
  profile.GetMultiInfo(NAME_MIDDLE, &middle_names);
  std::vector<string16> last_names;
  profile.GetMultiInfo(NAME_LAST, &last_names);
  DCHECK_EQ(first_names.size(), middle_names.size());
  DCHECK_EQ(middle_names.size(), last_names.size());

  for (size_t i = 0; i < first_names.size(); ++i) {
    // Add the new name.
    sql::Statement s(db->GetUniqueStatement(
      "INSERT INTO autofill_profile_names"
      " (guid, first_name, middle_name, last_name) "
      "VALUES (?,?,?,?)"));
    if (!s) {
      NOTREACHED();
      return false;
    }
    s.BindString(0, profile.guid());
    s.BindString16(1, first_names[i]);
    s.BindString16(2, middle_names[i]);
    s.BindString16(3, last_names[i]);

    if (!s.Run()) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AddAutofillProfileEmails(const AutofillProfile& profile,
                              sql::Connection* db) {
  std::vector<string16> emails;
  profile.GetMultiInfo(EMAIL_ADDRESS, &emails);

  for (size_t i = 0; i < emails.size(); ++i) {
    // Add the new email.
    sql::Statement s(db->GetUniqueStatement(
      "INSERT INTO autofill_profile_emails"
      " (guid, email) "
      "VALUES (?,?)"));
    if (!s) {
      NOTREACHED();
      return false;
    }
    s.BindString(0, profile.guid());
    s.BindString16(1, emails[i]);

    if (!s.Run()) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AddAutofillProfilePhones(const AutofillProfile& profile,
                              AutofillPhoneType phone_type,
                              sql::Connection* db) {
  AutofillFieldType field_type;
  if (phone_type == kAutofillPhoneNumber) {
    field_type = PHONE_HOME_WHOLE_NUMBER;
  } else if (phone_type == kAutofillFaxNumber) {
    field_type = PHONE_FAX_WHOLE_NUMBER;
  } else {
    NOTREACHED();
    return false;
  }

  std::vector<string16> numbers;
  profile.GetMultiInfo(field_type, &numbers);

  for (size_t i = 0; i < numbers.size(); ++i) {
    // Add the new number.
    sql::Statement s(db->GetUniqueStatement(
      "INSERT INTO autofill_profile_phones"
      " (guid, type, number) "
      "VALUES (?,?,?)"));
    if (!s) {
      NOTREACHED();
      return false;
    }
    s.BindString(0, profile.guid());
    s.BindInt(1, phone_type);
    s.BindString16(2, numbers[i]);

    if (!s.Run()) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AddAutofillProfilePieces(const AutofillProfile& profile,
                              sql::Connection* db) {
  if (!AddAutofillProfileNames(profile, db))
    return false;

  if (!AddAutofillProfileEmails(profile, db))
    return false;

  if (!AddAutofillProfilePhones(profile, kAutofillPhoneNumber, db))
    return false;

  if (!AddAutofillProfilePhones(profile, kAutofillFaxNumber, db))
    return false;

  return true;
}

bool RemoveAutofillProfilePieces(const std::string& guid, sql::Connection* db) {
  sql::Statement s1(db->GetUniqueStatement(
      "DELETE FROM autofill_profile_names WHERE guid = ?"));
  if (!s1) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s1.BindString(0, guid);
  if (!s1.Run())
    return false;

  sql::Statement s2(db->GetUniqueStatement(
      "DELETE FROM autofill_profile_emails WHERE guid = ?"));
  if (!s2) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s2.BindString(0, guid);
  if (!s2.Run())
    return false;

  sql::Statement s3(db->GetUniqueStatement(
      "DELETE FROM autofill_profile_phones WHERE guid = ?"));
  if (!s3) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s3.BindString(0, guid);
  return s3.Run();
}

}  // namespace

bool AutofillTable::Init() {
 return (InitMainTable() && InitCreditCardsTable() && InitDatesTable() &&
     InitProfilesTable() && InitProfileNamesTable() &&
     InitProfileEmailsTable() && InitProfilePhonesTable() &&
     InitProfileTrashTable());
}

bool AutofillTable::IsSyncable() {
  return true;
}

bool AutofillTable::AddFormFieldValues(const std::vector<FormField>& elements,
                                       std::vector<AutofillChange>* changes) {
  return AddFormFieldValuesTime(elements, changes, Time::Now());
}

bool AutofillTable::AddFormFieldValue(const FormField& element,
                                      std::vector<AutofillChange>* changes) {
  return AddFormFieldValueTime(element, changes, base::Time::Now());
}

bool AutofillTable::GetFormValuesForElementName(const string16& name,
                                                const string16& prefix,
                                                std::vector<string16>* values,
                                                int limit) {
  DCHECK(values);
  sql::Statement s;

  if (prefix.empty()) {
    s.Assign(db_->GetUniqueStatement(
        "SELECT value FROM autofill "
        "WHERE name = ? "
        "ORDER BY count DESC "
        "LIMIT ?"));
    if (!s) {
      NOTREACHED() << "Statement prepare failed";
      return false;
    }

    s.BindString16(0, name);
    s.BindInt(1, limit);
  } else {
    string16 prefix_lower = l10n_util::ToLower(prefix);
    string16 next_prefix = prefix_lower;
    next_prefix[next_prefix.length() - 1]++;

    s.Assign(db_->GetUniqueStatement(
        "SELECT value FROM autofill "
        "WHERE name = ? AND "
        "value_lower >= ? AND "
        "value_lower < ? "
        "ORDER BY count DESC "
        "LIMIT ?"));
    if (!s) {
      NOTREACHED() << "Statement prepare failed";
      return false;
    }

    s.BindString16(0, name);
    s.BindString16(1, prefix_lower);
    s.BindString16(2, next_prefix);
    s.BindInt(3, limit);
  }

  values->clear();
  while (s.Step())
    values->push_back(s.ColumnString16(0));
  return s.Succeeded();
}

bool AutofillTable::RemoveFormElementsAddedBetween(
    base::Time delete_begin,
    base::Time delete_end,
    std::vector<AutofillChange>* changes) {
  DCHECK(changes);
  // Query for the pair_id, name, and value of all form elements that
  // were used between the given times.
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT DISTINCT a.pair_id, a.name, a.value "
      "FROM autofill_dates ad JOIN autofill a ON ad.pair_id = a.pair_id "
      "WHERE ad.date_created >= ? AND ad.date_created < ?"));
  if (!s) {
    NOTREACHED() << "Statement 1 prepare failed";
    return false;
  }
  s.BindInt64(0, delete_begin.ToTimeT());
  s.BindInt64(1,
              delete_end.is_null() ?
                  std::numeric_limits<int64>::max() :
                  delete_end.ToTimeT());

  AutofillElementList elements;
  while (s.Step()) {
    elements.push_back(MakeTuple(s.ColumnInt64(0),
                                 s.ColumnString16(1),
                                 s.ColumnString16(2)));
  }

  if (!s.Succeeded()) {
    NOTREACHED();
    return false;
  }

  for (AutofillElementList::iterator itr = elements.begin();
       itr != elements.end(); itr++) {
    int how_many = 0;
    if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end,
                                       &how_many)) {
      return false;
    }
    bool was_removed = false;
    if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed))
      return false;
    AutofillChange::Type change_type =
        was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE;
    changes->push_back(AutofillChange(change_type,
                                      AutofillKey(itr->b, itr->c)));
  }

  return true;
}

bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id,
                                                  const Time delete_begin,
                                                  const Time delete_end,
                                                  int* how_many) {
  sql::Statement s(db_->GetUniqueStatement(
      "DELETE FROM autofill_dates WHERE pair_id = ? AND "
      "date_created >= ? AND date_created < ?"));
  if (!s) {
    NOTREACHED() << "Statement 1 prepare failed";
    return false;
  }
  s.BindInt64(0, pair_id);
  s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT());
  s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() :
                                        delete_end.ToTimeT());

  bool result = s.Run();
  if (how_many)
    *how_many = db_->GetLastChangeCount();

  return result;
}

bool AutofillTable::AddToCountOfFormElement(int64 pair_id,
                                            int delta,
                                            bool* was_removed) {
  DCHECK(was_removed);
  int count = 0;
  *was_removed = false;

  if (!GetCountOfFormElement(pair_id, &count))
    return false;

  if (count + delta == 0) {
    if (!RemoveFormElementForID(pair_id))
      return false;
    *was_removed = true;
  } else {
    if (!SetCountOfFormElement(pair_id, count + delta))
      return false;
  }
  return true;
}

bool AutofillTable::GetIDAndCountOfFormElement(
    const FormField& element,
    int64* pair_id,
    int* count) {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT pair_id, count FROM autofill "
      "WHERE name = ? AND value = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString16(0, element.name);
  s.BindString16(1, element.value);

  *pair_id = 0;
  *count = 0;

  if (s.Step()) {
    *pair_id = s.ColumnInt64(0);
    *count = s.ColumnInt(1);
  }

  return true;
}

bool AutofillTable::GetCountOfFormElement(int64 pair_id, int* count) {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT count FROM autofill WHERE pair_id = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindInt64(0, pair_id);

  if (s.Step()) {
    *count = s.ColumnInt(0);
    return true;
  }
  return false;
}

bool AutofillTable::SetCountOfFormElement(int64 pair_id, int count) {
  sql::Statement s(db_->GetUniqueStatement(
      "UPDATE autofill SET count = ? WHERE pair_id = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindInt(0, count);
  s.BindInt64(1, pair_id);
  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool AutofillTable::InsertFormElement(const FormField& element,
                                      int64* pair_id) {
  sql::Statement s(db_->GetUniqueStatement(
      "INSERT INTO autofill (name, value, value_lower) VALUES (?,?,?)"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString16(0, element.name);
  s.BindString16(1, element.value);
  s.BindString16(2, l10n_util::ToLower(element.value));

  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  *pair_id = db_->GetLastInsertRowId();
  return true;
}

bool AutofillTable::InsertPairIDAndDate(int64 pair_id,
                                        base::Time date_created) {
  sql::Statement s(db_->GetUniqueStatement(
      "INSERT INTO autofill_dates "
      "(pair_id, date_created) VALUES (?, ?)"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindInt64(0, pair_id);
  s.BindInt64(1, date_created.ToTimeT());

  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool AutofillTable::AddFormFieldValuesTime(
    const std::vector<FormField>& elements,
    std::vector<AutofillChange>* changes,
    base::Time time) {
  // Only add one new entry for each unique element name.  Use |seen_names| to
  // track this.  Add up to |kMaximumUniqueNames| unique entries per form.
  const size_t kMaximumUniqueNames = 256;
  std::set<string16> seen_names;
  bool result = true;
  for (std::vector<FormField>::const_iterator
       itr = elements.begin();
       itr != elements.end();
       itr++) {
    if (seen_names.size() >= kMaximumUniqueNames)
      break;
    if (seen_names.find(itr->name) != seen_names.end())
      continue;
    result = result && AddFormFieldValueTime(*itr, changes, time);
    seen_names.insert(itr->name);
  }
  return result;
}

bool AutofillTable::ClearAutofillEmptyValueElements() {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT pair_id FROM autofill WHERE TRIM(value)= \"\""));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  std::set<int64> ids;
  while (s.Step())
    ids.insert(s.ColumnInt64(0));

  bool success = true;
  for (std::set<int64>::const_iterator iter = ids.begin(); iter != ids.end();
       ++iter) {
    if (!RemoveFormElementForID(*iter))
      success = false;
  }

  return success;
}

bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) {
  DCHECK(entries);
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT name, value, date_created FROM autofill a JOIN "
      "autofill_dates ad ON a.pair_id=ad.pair_id"));

  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  bool first_entry = true;
  AutofillKey* current_key_ptr = NULL;
  std::vector<base::Time>* timestamps_ptr = NULL;
  string16 name, value;
  base::Time time;
  while (s.Step()) {
    name = s.ColumnString16(0);
    value = s.ColumnString16(1);
    time = Time::FromTimeT(s.ColumnInt64(2));

    if (first_entry) {
      current_key_ptr = new AutofillKey(name, value);

      timestamps_ptr = new std::vector<base::Time>;
      timestamps_ptr->push_back(time);

      first_entry = false;
    } else {
      // we've encountered the next entry
      if (current_key_ptr->name().compare(name) != 0 ||
          current_key_ptr->value().compare(value) != 0) {
        AutofillEntry entry(*current_key_ptr, *timestamps_ptr);
        entries->push_back(entry);

        delete current_key_ptr;
        delete timestamps_ptr;

        current_key_ptr = new AutofillKey(name, value);
        timestamps_ptr = new std::vector<base::Time>;
      }
      timestamps_ptr->push_back(time);
    }
  }
  // If there is at least one result returned, first_entry will be false.
  // For this case we need to do a final cleanup step.
  if (!first_entry) {
    AutofillEntry entry(*current_key_ptr, *timestamps_ptr);
    entries->push_back(entry);
    delete current_key_ptr;
    delete timestamps_ptr;
  }

  return s.Succeeded();
}

bool AutofillTable::GetAutofillTimestamps(const string16& name,
                                          const string16& value,
                                          std::vector<base::Time>* timestamps) {
  DCHECK(timestamps);
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT date_created FROM autofill a JOIN "
      "autofill_dates ad ON a.pair_id=ad.pair_id "
      "WHERE a.name = ? AND a.value = ?"));

  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString16(0, name);
  s.BindString16(1, value);
  while (s.Step()) {
    timestamps->push_back(Time::FromTimeT(s.ColumnInt64(0)));
  }

  return s.Succeeded();
}

bool AutofillTable::UpdateAutofillEntries(
    const std::vector<AutofillEntry>& entries) {
  if (!entries.size())
    return true;

  // Remove all existing entries.
  for (size_t i = 0; i < entries.size(); i++) {
    std::string sql = "SELECT pair_id FROM autofill "
                      "WHERE name = ? AND value = ?";
    sql::Statement s(db_->GetUniqueStatement(sql.c_str()));
    if (!s.is_valid()) {
      NOTREACHED() << "Statement prepare failed";
      return false;
    }

    s.BindString16(0, entries[i].key().name());
    s.BindString16(1, entries[i].key().value());
    if (s.Step()) {
      if (!RemoveFormElementForID(s.ColumnInt64(0)))
        return false;
    }
  }

  // Insert all the supplied autofill entries.
  for (size_t i = 0; i < entries.size(); i++) {
    if (!InsertAutofillEntry(entries[i]))
      return false;
  }

  return true;
}

bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) {
  std::string sql = "INSERT INTO autofill (name, value, value_lower, count) "
                    "VALUES (?, ?, ?, ?)";
  sql::Statement s(db_->GetUniqueStatement(sql.c_str()));
  if (!s.is_valid()) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString16(0, entry.key().name());
  s.BindString16(1, entry.key().value());
  s.BindString16(2, l10n_util::ToLower(entry.key().value()));
  s.BindInt(3, entry.timestamps().size());

  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  int64 pair_id = db_->GetLastInsertRowId();
  for (size_t i = 0; i < entry.timestamps().size(); i++) {
    if (!InsertPairIDAndDate(pair_id, entry.timestamps()[i]))
      return false;
  }

  return true;
}

bool AutofillTable::AddFormFieldValueTime(const FormField& element,
                                          std::vector<AutofillChange>* changes,
                                          base::Time time) {
  int count = 0;
  int64 pair_id;

  if (!GetIDAndCountOfFormElement(element, &pair_id, &count))
    return false;

  if (count == 0 && !InsertFormElement(element, &pair_id))
    return false;

  if (!SetCountOfFormElement(pair_id, count + 1))
    return false;

  if (!InsertPairIDAndDate(pair_id, time))
    return false;

  AutofillChange::Type change_type =
      count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE;
  changes->push_back(
      AutofillChange(change_type,
                     AutofillKey(element.name, element.value)));
  return true;
}


bool AutofillTable::RemoveFormElement(const string16& name,
                                      const string16& value) {
  // Find the id for that pair.
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT pair_id FROM autofill WHERE  name = ? AND value= ?"));
  if (!s) {
    NOTREACHED() << "Statement 1 prepare failed";
    return false;
  }
  s.BindString16(0, name);
  s.BindString16(1, value);

  if (s.Step())
    return RemoveFormElementForID(s.ColumnInt64(0));
  return false;
}

bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) {
  if (IsAutofillGUIDInTrash(profile.guid()))
    return true;

  sql::Statement s(db_->GetUniqueStatement(
      "INSERT INTO autofill_profiles"
      "(guid, company_name, address_line_1, address_line_2, city, state,"
      " zipcode, country, country_code, date_modified)"
      "VALUES (?,?,?,?,?,?,?,?,?,?)"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  BindAutofillProfileToStatement(profile, &s);

  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  if (!s.Succeeded())
    return false;

  return AddAutofillProfilePieces(profile, db_);
}

bool AutofillTable::GetAutofillProfile(const std::string& guid,
                                       AutofillProfile** profile) {
  DCHECK(guid::IsValidGUID(guid));
  DCHECK(profile);
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid, company_name, address_line_1, address_line_2, city, state,"
      " zipcode, country, country_code, date_modified "
      "FROM autofill_profiles "
      "WHERE guid=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString(0, guid);
  if (!s.Step())
    return false;

  if (!s.Succeeded())
    return false;

  scoped_ptr<AutofillProfile> p(AutofillProfileFromStatement(s));

  // Get associated name info.
  AddAutofillProfileNamesToProfile(db_, p.get());

  // Get associated email info.
  AddAutofillProfileEmailsToProfile(db_, p.get());

  // Get associated phone info.
  AddAutofillProfilePhonesToProfile(db_, p.get());

  // Get associated fax info.
  AddAutofillProfileFaxesToProfile(db_, p.get());

  *profile = p.release();
  return true;
}

bool AutofillTable::GetAutofillProfiles(
    std::vector<AutofillProfile*>* profiles) {
  DCHECK(profiles);
  profiles->clear();

  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid "
      "FROM autofill_profiles"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  while (s.Step()) {
    std::string guid = s.ColumnString(0);
    AutofillProfile* profile = NULL;
    if (!GetAutofillProfile(guid, &profile))
      return false;
    profiles->push_back(profile);
  }

  return s.Succeeded();
}

bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) {
  DCHECK(guid::IsValidGUID(profile.guid()));

  // Don't update anything until the trash has been emptied.  There may be
  // pending modifications to process.
  if (!IsAutofillProfilesTrashEmpty())
    return true;

  AutofillProfile* tmp_profile = NULL;
  if (!GetAutofillProfile(profile.guid(), &tmp_profile))
    return false;

  // Preserve appropriate modification dates by not updating unchanged profiles.
  scoped_ptr<AutofillProfile> old_profile(tmp_profile);
  if (old_profile->Compare(profile) == 0)
    return true;

  AutofillProfile new_profile(profile);
  std::vector<string16> values;

  old_profile->GetMultiInfo(NAME_FULL, &values);
  values[0] = new_profile.GetInfo(NAME_FULL);
  new_profile.SetMultiInfo(NAME_FULL, values);

  old_profile->GetMultiInfo(EMAIL_ADDRESS, &values);
  values[0] = new_profile.GetInfo(EMAIL_ADDRESS);
  new_profile.SetMultiInfo(EMAIL_ADDRESS, values);

  old_profile->GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
  values[0] = new_profile.GetInfo(PHONE_HOME_WHOLE_NUMBER);
  new_profile.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);

  old_profile->GetMultiInfo(PHONE_FAX_WHOLE_NUMBER, &values);
  values[0] = new_profile.GetInfo(PHONE_FAX_WHOLE_NUMBER);
  new_profile.SetMultiInfo(PHONE_FAX_WHOLE_NUMBER, values);

  return UpdateAutofillProfileMulti(new_profile);
}

bool AutofillTable::UpdateAutofillProfileMulti(const AutofillProfile& profile) {
  DCHECK(guid::IsValidGUID(profile.guid()));

  // Don't update anything until the trash has been emptied.  There may be
  // pending modifications to process.
  if (!IsAutofillProfilesTrashEmpty())
    return true;

  AutofillProfile* tmp_profile = NULL;
  if (!GetAutofillProfile(profile.guid(), &tmp_profile))
    return false;

  // Preserve appropriate modification dates by not updating unchanged profiles.
  scoped_ptr<AutofillProfile> old_profile(tmp_profile);
  if (old_profile->CompareMulti(profile) == 0)
    return true;

  sql::Statement s(db_->GetUniqueStatement(
      "UPDATE autofill_profiles "
      "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, "
      "    city=?, state=?, zipcode=?, country=?, country_code=?, "
      "    date_modified=? "
      "WHERE guid=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  BindAutofillProfileToStatement(profile, &s);
  s.BindString(10, profile.guid());
  bool result = s.Run();
  DCHECK_GT(db_->GetLastChangeCount(), 0);
  if (!result)
    return result;

  // Remove the old names, emails, and phone/fax numbers.
  if (!RemoveAutofillProfilePieces(profile.guid(), db_))
    return false;

  return AddAutofillProfilePieces(profile, db_);
}

bool AutofillTable::RemoveAutofillProfile(const std::string& guid) {
  DCHECK(guid::IsValidGUID(guid));

  if (IsAutofillGUIDInTrash(guid)) {
    sql::Statement s_trash(db_->GetUniqueStatement(
        "DELETE FROM autofill_profiles_trash WHERE guid = ?"));
    if (!s_trash) {
      NOTREACHED() << "Statement prepare failed";
      return false;
    }
    s_trash.BindString(0, guid);
    if (!s_trash.Run()) {
      NOTREACHED() << "Expected item in trash.";
      return false;
    }

    return true;
  }

  sql::Statement s(db_->GetUniqueStatement(
      "DELETE FROM autofill_profiles WHERE guid = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString(0, guid);
  if (!s.Run())
    return false;

  return RemoveAutofillProfilePieces(guid, db_);
}

bool AutofillTable::ClearAutofillProfiles() {
  sql::Statement s1(db_->GetUniqueStatement(
      "DELETE FROM autofill_profiles"));
  if (!s1) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  if (!s1.Run())
    return false;

  sql::Statement s2(db_->GetUniqueStatement(
      "DELETE FROM autofill_profile_names"));
  if (!s2) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  if (!s2.Run())
    return false;

  sql::Statement s3(db_->GetUniqueStatement(
      "DELETE FROM autofill_profile_emails"));
  if (!s3) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  if (!s3.Run())
    return false;

  sql::Statement s4(db_->GetUniqueStatement(
      "DELETE FROM autofill_profile_phones"));
  if (!s4) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  if (!s4.Run())
    return false;

  return true;
}

bool AutofillTable::AddCreditCard(const CreditCard& credit_card) {
  sql::Statement s(db_->GetUniqueStatement(
      "INSERT INTO credit_cards"
      "(guid, name_on_card, expiration_month, expiration_year, "
      "card_number_encrypted, date_modified)"
      "VALUES (?,?,?,?,?,?)"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  BindCreditCardToStatement(credit_card, &s);

  if (!s.Run()) {
    NOTREACHED();
    return false;
  }

  DCHECK_GT(db_->GetLastChangeCount(), 0);
  return s.Succeeded();
}

bool AutofillTable::GetCreditCard(const std::string& guid,
                                  CreditCard** credit_card) {
  DCHECK(guid::IsValidGUID(guid));
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid, name_on_card, expiration_month, expiration_year, "
      "card_number_encrypted, date_modified "
      "FROM credit_cards "
      "WHERE guid = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString(0, guid);
  if (!s.Step())
    return false;

  *credit_card = CreditCardFromStatement(s);

  return s.Succeeded();
}

bool AutofillTable::GetCreditCards(
    std::vector<CreditCard*>* credit_cards) {
  DCHECK(credit_cards);
  credit_cards->clear();

  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid "
      "FROM credit_cards"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  while (s.Step()) {
    std::string guid = s.ColumnString(0);
    CreditCard* credit_card = NULL;
    if (!GetCreditCard(guid, &credit_card))
      return false;
    credit_cards->push_back(credit_card);
  }

  return s.Succeeded();
}

bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) {
  DCHECK(guid::IsValidGUID(credit_card.guid()));

  CreditCard* tmp_credit_card = NULL;
  if (!GetCreditCard(credit_card.guid(), &tmp_credit_card))
    return false;

  // Preserve appropriate modification dates by not updating unchanged cards.
  scoped_ptr<CreditCard> old_credit_card(tmp_credit_card);
  if (*old_credit_card == credit_card)
    return true;

  sql::Statement s(db_->GetUniqueStatement(
      "UPDATE credit_cards "
      "SET guid=?, name_on_card=?, expiration_month=?, "
      "    expiration_year=?, card_number_encrypted=?, date_modified=? "
      "WHERE guid=?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  BindCreditCardToStatement(credit_card, &s);
  s.BindString(6, credit_card.guid());
  bool result = s.Run();
  DCHECK_GT(db_->GetLastChangeCount(), 0);
  return result;
}

bool AutofillTable::RemoveCreditCard(const std::string& guid) {
  DCHECK(guid::IsValidGUID(guid));
  sql::Statement s(db_->GetUniqueStatement(
      "DELETE FROM credit_cards WHERE guid = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString(0, guid);
  return s.Run();
}

bool AutofillTable::RemoveAutofillProfilesAndCreditCardsModifiedBetween(
    base::Time delete_begin,
    base::Time delete_end,
    std::vector<std::string>* profile_guids,
    std::vector<std::string>* credit_card_guids) {
  DCHECK(delete_end.is_null() || delete_begin < delete_end);

  time_t delete_begin_t = delete_begin.ToTimeT();
  time_t delete_end_t = delete_end.is_null() ?
      std::numeric_limits<time_t>::max() :
      delete_end.ToTimeT();

  // Remember Autofill profiles in the time range.
  sql::Statement s_profiles_get(db_->GetUniqueStatement(
      "SELECT guid FROM autofill_profiles "
      "WHERE date_modified >= ? AND date_modified < ?"));
  if (!s_profiles_get) {
    NOTREACHED() << "Autofill profiles statement prepare failed";
    return false;
  }

  s_profiles_get.BindInt64(0, delete_begin_t);
  s_profiles_get.BindInt64(1, delete_end_t);
  profile_guids->clear();
  while (s_profiles_get.Step()) {
    std::string guid = s_profiles_get.ColumnString(0);
    profile_guids->push_back(guid);
  }

  // Remove Autofill profiles in the time range.
  sql::Statement s_profiles(db_->GetUniqueStatement(
      "DELETE FROM autofill_profiles "
      "WHERE date_modified >= ? AND date_modified < ?"));
  if (!s_profiles) {
    NOTREACHED() << "Autofill profiles statement prepare failed";
    return false;
  }

  s_profiles.BindInt64(0, delete_begin_t);
  s_profiles.BindInt64(1, delete_end_t);
  s_profiles.Run();

  if (!s_profiles.Succeeded()) {
    NOTREACHED();
    return false;
  }

  // Remember Autofill credit cards in the time range.
  sql::Statement s_credit_cards_get(db_->GetUniqueStatement(
      "SELECT guid FROM credit_cards "
      "WHERE date_modified >= ? AND date_modified < ?"));
  if (!s_credit_cards_get) {
    NOTREACHED() << "Autofill profiles statement prepare failed";
    return false;
  }

  s_credit_cards_get.BindInt64(0, delete_begin_t);
  s_credit_cards_get.BindInt64(1, delete_end_t);
  credit_card_guids->clear();
  while (s_credit_cards_get.Step()) {
    std::string guid = s_credit_cards_get.ColumnString(0);
    credit_card_guids->push_back(guid);
  }

  // Remove Autofill credit cards in the time range.
  sql::Statement s_credit_cards(db_->GetUniqueStatement(
      "DELETE FROM credit_cards "
      "WHERE date_modified >= ? AND date_modified < ?"));
  if (!s_credit_cards) {
    NOTREACHED() << "Autofill credit cards statement prepare failed";
    return false;
  }

  s_credit_cards.BindInt64(0, delete_begin_t);
  s_credit_cards.BindInt64(1, delete_end_t);
  s_credit_cards.Run();

  if (!s_credit_cards.Succeeded()) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool AutofillTable::GetAutofillProfilesInTrash(
    std::vector<std::string>* guids) {
  guids->clear();

  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid "
      "FROM autofill_profiles_trash"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  while (s.Step()) {
    std::string guid = s.ColumnString(0);
    guids->push_back(guid);
  }

  return s.Succeeded();
}

bool AutofillTable::EmptyAutofillProfilesTrash() {
  sql::Statement s(db_->GetUniqueStatement(
      "DELETE FROM autofill_profiles_trash"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  return s.Run();
}


bool AutofillTable::RemoveFormElementForID(int64 pair_id) {
  sql::Statement s(db_->GetUniqueStatement(
      "DELETE FROM autofill WHERE pair_id = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }
  s.BindInt64(0, pair_id);
  if (s.Run()) {
    return RemoveFormElementForTimeRange(pair_id, base::Time(), base::Time(),
                                         NULL);
  }
  return false;
}

bool AutofillTable::AddAutofillGUIDToTrash(const std::string& guid) {
  sql::Statement s(db_->GetUniqueStatement(
    "INSERT INTO autofill_profiles_trash"
    " (guid) "
    "VALUES (?)"));
  if (!s) {
    NOTREACHED();
    return sql::INIT_FAILURE;
  }

  s.BindString(0, guid);
  if (!s.Run()) {
    NOTREACHED();
    return false;
  }
  return true;
}

bool AutofillTable::IsAutofillProfilesTrashEmpty() {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid "
      "FROM autofill_profiles_trash"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  return !s.Step();
}

bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid "
      "FROM autofill_profiles_trash "
      "WHERE guid = ?"));
  if (!s) {
    NOTREACHED() << "Statement prepare failed";
    return false;
  }

  s.BindString(0, guid);
  return s.Step();
}

bool AutofillTable::InitMainTable() {
  if (!db_->DoesTableExist("autofill")) {
    if (!db_->Execute("CREATE TABLE autofill ("
                      "name VARCHAR, "
                      "value VARCHAR, "
                      "value_lower VARCHAR, "
                      "pair_id INTEGER PRIMARY KEY, "
                      "count INTEGER DEFAULT 1)")) {
      NOTREACHED();
      return false;
    }
    if (!db_->Execute("CREATE INDEX autofill_name ON autofill (name)")) {
       NOTREACHED();
       return false;
    }
    if (!db_->Execute("CREATE INDEX autofill_name_value_lower ON "
                      "autofill (name, value_lower)")) {
       NOTREACHED();
       return false;
    }
  }
  return true;
}

bool AutofillTable::InitCreditCardsTable() {
  if (!db_->DoesTableExist("credit_cards")) {
    if (!db_->Execute("CREATE TABLE credit_cards ( "
                      "guid VARCHAR PRIMARY KEY, "
                      "name_on_card VARCHAR, "
                      "expiration_month INTEGER, "
                      "expiration_year INTEGER, "
                      "card_number_encrypted BLOB, "
                      "date_modified INTEGER NOT NULL DEFAULT 0)")) {
      NOTREACHED();
      return false;
    }
  }

  return true;
}

bool AutofillTable::InitDatesTable() {
  if (!db_->DoesTableExist("autofill_dates")) {
    if (!db_->Execute("CREATE TABLE autofill_dates ( "
                      "pair_id INTEGER DEFAULT 0, "
                      "date_created INTEGER DEFAULT 0)")) {
      NOTREACHED();
      return false;
    }
    if (!db_->Execute("CREATE INDEX autofill_dates_pair_id ON "
                      "autofill_dates (pair_id)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AutofillTable::InitProfilesTable() {
  if (!db_->DoesTableExist("autofill_profiles")) {
    if (!db_->Execute("CREATE TABLE autofill_profiles ( "
                      "guid VARCHAR PRIMARY KEY, "
                      "company_name VARCHAR, "
                      "address_line_1 VARCHAR, "
                      "address_line_2 VARCHAR, "
                      "city VARCHAR, "
                      "state VARCHAR, "
                      "zipcode VARCHAR, "
                      "country VARCHAR, "
                      "country_code VARCHAR, "
                      "date_modified INTEGER NOT NULL DEFAULT 0)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AutofillTable::InitProfileNamesTable() {
  if (!db_->DoesTableExist("autofill_profile_names")) {
    if (!db_->Execute("CREATE TABLE autofill_profile_names ( "
                      "guid VARCHAR, "
                      "first_name VARCHAR, "
                      "middle_name VARCHAR, "
                      "last_name VARCHAR)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AutofillTable::InitProfileEmailsTable() {
  if (!db_->DoesTableExist("autofill_profile_emails")) {
    if (!db_->Execute("CREATE TABLE autofill_profile_emails ( "
                      "guid VARCHAR, "
                      "email VARCHAR)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AutofillTable::InitProfilePhonesTable() {
  if (!db_->DoesTableExist("autofill_profile_phones")) {
    if (!db_->Execute("CREATE TABLE autofill_profile_phones ( "
                      "guid VARCHAR, "
                      "type INTEGER DEFAULT 0, "
                      "number VARCHAR)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool AutofillTable::InitProfileTrashTable() {
  if (!db_->DoesTableExist("autofill_profiles_trash")) {
    if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( "
                      "guid VARCHAR)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

// Add the card_number_encrypted column if credit card table was not
// created in this build (otherwise the column already exists).
// WARNING: Do not change the order of the execution of the SQL
// statements in this case!  Profile corruption and data migration
// issues WILL OCCUR. See http://crbug.com/10913
//
// The problem is that if a user has a profile which was created before
// r37036, when the credit_cards table was added, and then failed to
// update this profile between the credit card addition and the addition
// of the "encrypted" columns (44963), the next data migration will put
// the user's profile in an incoherent state: The user will update from
// a data profile set to be earlier than 22, and therefore pass through
// this update case.  But because the user did not have a credit_cards
// table before starting Chrome, it will have just been initialized
// above, and so already have these columns -- and thus this data
// update step will have failed.
//
// The false assumption in this case is that at this step in the
// migration, the user has a credit card table, and that this
// table does not include encrypted columns!
// Because this case does not roll back the complete set of SQL
// transactions properly in case of failure (that is, it does not
// roll back the table initialization done above), the incoherent
// profile will now see itself as being at version 22 -- but include a
// fully initialized credit_cards table.  Every time Chrome runs, it
// will try to update the web database and fail at this step, unless
// we allow for the faulty assumption described above by checking for
// the existence of the columns only AFTER we've executed the commands
// to add them.
bool AutofillTable::MigrateToVersion23AddCardNumberEncryptedColumn() {
  if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) {
    if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
                      "card_number_encrypted BLOB DEFAULT NULL")) {
      LOG(WARNING) << "Could not add card_number_encrypted to "
                      "credit_cards table.";
      return false;
    }
  }

  if (!db_->DoesColumnExist("credit_cards", "verification_code_encrypted")) {
    if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
                      "verification_code_encrypted BLOB DEFAULT NULL")) {
      LOG(WARNING) << "Could not add verification_code_encrypted to "
                      "credit_cards table.";
      return false;
    }
  }

  return true;
}

// One-time cleanup for http://crbug.com/38364 - In the presence of
// multi-byte UTF-8 characters, that bug could cause Autofill strings
// to grow larger and more corrupt with each save.  The cleanup removes
// any row with a string field larger than a reasonable size.  The string
// fields examined here are precisely the ones that were subject to
// corruption by the original bug.
bool AutofillTable::MigrateToVersion24CleanupOversizedStringFields() {
  const std::string autofill_is_too_big =
      "max(length(name), length(value)) > 500";

  const std::string credit_cards_is_too_big =
      "max(length(label), length(name_on_card), length(type), "
      "    length(expiration_month), length(expiration_year), "
      "    length(billing_address), length(shipping_address) "
      ") > 500";

  const std::string autofill_profiles_is_too_big =
      "max(length(label), length(first_name), "
      "    length(middle_name), length(last_name), length(email), "
      "    length(company_name), length(address_line_1), "
      "    length(address_line_2), length(city), length(state), "
      "    length(zipcode), length(country), length(phone), "
      "    length(fax)) > 500";

  std::string query = "DELETE FROM autofill_dates WHERE pair_id IN ("
      "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")";

  if (!db_->Execute(query.c_str()))
    return false;

  query = "DELETE FROM autofill WHERE " + autofill_is_too_big;

  if (!db_->Execute(query.c_str()))
    return false;

  // Only delete from legacy credit card tables where specific columns exist.
  if (db_->DoesColumnExist("credit_cards", "label") &&
      db_->DoesColumnExist("credit_cards", "name_on_card") &&
      db_->DoesColumnExist("credit_cards", "type") &&
      db_->DoesColumnExist("credit_cards", "expiration_month") &&
      db_->DoesColumnExist("credit_cards", "expiration_year") &&
      db_->DoesColumnExist("credit_cards", "billing_address") &&
      db_->DoesColumnExist("credit_cards", "shipping_address") &&
      db_->DoesColumnExist("autofill_profiles", "label")) {
    query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big +
        ") OR label IN (SELECT label FROM autofill_profiles WHERE " +
        autofill_profiles_is_too_big + ")";

    if (!db_->Execute(query.c_str()))
      return false;
  }

  if (db_->DoesColumnExist("autofill_profiles", "label")) {
    query = "DELETE FROM autofill_profiles WHERE " +
        autofill_profiles_is_too_big;

    if (!db_->Execute(query.c_str()))
      return false;
  }

  return true;
}

// Change the credit_cards.billing_address column from a string to an
// int.  The stored string is the label of an address, so we have to
// select the unique ID of this address using the label as a foreign
// key into the |autofill_profiles| table.
bool AutofillTable::MigrateToVersion27UpdateLegacyCreditCards() {
  // Only migrate from legacy credit card tables where specific columns
  // exist.
  if (!(db_->DoesColumnExist("credit_cards", "unique_id") &&
        db_->DoesColumnExist("credit_cards", "billing_address") &&
        db_->DoesColumnExist("autofill_profiles", "unique_id"))) {
    return true;
  }

  std::string stmt =
      "SELECT credit_cards.unique_id, autofill_profiles.unique_id "
      "FROM autofill_profiles, credit_cards "
      "WHERE credit_cards.billing_address = autofill_profiles.label";
  sql::Statement s(db_->GetUniqueStatement(stmt.c_str()));
  if (!s)
    return false;

  std::map<int, int> cc_billing_map;
  while (s.Step())
    cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1);

  // Windows already stores the IDs as strings in |billing_address|. Try
  // to convert those.
  if (cc_billing_map.empty()) {
    std::string stmt = "SELECT unique_id,billing_address FROM credit_cards";
    sql::Statement s(db_->GetUniqueStatement(stmt.c_str()));
    if (!s)
      return false;

    while (s.Step()) {
      int id = 0;
      if (base::StringToInt(s.ColumnString(1), &id))
        cc_billing_map[s.ColumnInt(0)] = id;
    }
  }

  if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
                    "label VARCHAR, "
                    "unique_id INTEGER PRIMARY KEY, "
                    "name_on_card VARCHAR, "
                    "type VARCHAR, "
                    "card_number VARCHAR, "
                    "expiration_month INTEGER, "
                    "expiration_year INTEGER, "
                    "verification_code VARCHAR, "
                    "billing_address INTEGER, "
                    "shipping_address VARCHAR, "
                    "card_number_encrypted BLOB, "
                    "verification_code_encrypted BLOB)")) {
    return false;
  }

  if (!db_->Execute(
      "INSERT INTO credit_cards_temp "
      "SELECT label,unique_id,name_on_card,type,card_number,"
      "expiration_month,expiration_year,verification_code,0,"
      "shipping_address,card_number_encrypted,"
      "verification_code_encrypted FROM credit_cards")) {
    return false;
  }

  if (!db_->Execute("DROP TABLE credit_cards"))
    return false;

  if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
    return false;

  for (std::map<int, int>::const_iterator iter = cc_billing_map.begin();
       iter != cc_billing_map.end(); ++iter) {
    sql::Statement s(db_->GetCachedStatement(
        SQL_FROM_HERE,
        "UPDATE credit_cards SET billing_address=? WHERE unique_id=?"));
    if (!s)
      return false;

    s.BindInt(0, (*iter).second);
    s.BindInt(1, (*iter).first);

    if (!s.Run())
      return false;
  }

  return true;
}

bool AutofillTable::MigrateToVersion30AddDateModifed() {
  // Add date_modified to autofill_profiles.
  if (!db_->DoesColumnExist("autofill_profiles", "date_modified")) {
    if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
                      "date_modified INTEGER NON NULL DEFAULT 0")) {
      return false;
    }

    sql::Statement s(db_->GetUniqueStatement(
        "UPDATE autofill_profiles SET date_modified=?"));
    if (!s)
      return false;

    s.BindInt64(0, Time::Now().ToTimeT());

    if (!s.Run())
      return false;
  }

  // Add date_modified to credit_cards.
  if (!db_->DoesColumnExist("credit_cards", "date_modified")) {
    if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
                      "date_modified INTEGER NON NULL DEFAULT 0")) {
      return false;
    }

    sql::Statement s(db_->GetUniqueStatement(
        "UPDATE credit_cards SET date_modified=?"));
    if (!s)
      return false;

    s.BindInt64(0, Time::Now().ToTimeT());

    if (!s.Run())
      return false;
  }

  return true;
}

bool AutofillTable::MigrateToVersion31AddGUIDToCreditCardsAndProfiles() {
  // Note that we need to check for the guid column's existence due to the
  // fact that for a version 22 database the |autofill_profiles| table
  // gets created fresh with |InitAutofillProfilesTable|.
  if (!db_->DoesColumnExist("autofill_profiles", "guid")) {
    if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
                      "guid VARCHAR NOT NULL DEFAULT \"\"")) {
      return false;
    }

    // Set all the |guid| fields to valid values.

    sql::Statement s(db_->GetUniqueStatement("SELECT unique_id "
                                             "FROM autofill_profiles"));
    if (!s)
      return false;

    while (s.Step()) {
      sql::Statement update_s(
          db_->GetUniqueStatement("UPDATE autofill_profiles "
                                  "SET guid=? WHERE unique_id=?"));
      if (!update_s)
        return false;
      update_s.BindString(0, guid::GenerateGUID());
      update_s.BindInt(1, s.ColumnInt(0));

      if (!update_s.Run())
        return false;
    }
  }

  // Note that we need to check for the guid column's existence due to the
  // fact that for a version 22 database the |autofill_profiles| table
  // gets created fresh with |InitAutofillProfilesTable|.
  if (!db_->DoesColumnExist("credit_cards", "guid")) {
    if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN "
                      "guid VARCHAR NOT NULL DEFAULT \"\"")) {
      return false;
    }

    // Set all the |guid| fields to valid values.

    sql::Statement s(db_->GetUniqueStatement("SELECT unique_id "
                                             "FROM credit_cards"));
    if (!s)
      return false;

    while (s.Step()) {
      sql::Statement update_s(
          db_->GetUniqueStatement("UPDATE credit_cards "
                                  "set guid=? WHERE unique_id=?"));
      if (!update_s)
        return false;
      update_s.BindString(0, guid::GenerateGUID());
      update_s.BindInt(1, s.ColumnInt(0));

      if (!update_s.Run())
        return false;
    }
  }

  return true;
}

bool AutofillTable::MigrateToVersion32UpdateProfilesAndCreditCards() {
  if (db_->DoesColumnExist("autofill_profiles", "unique_id")) {
    if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( "
                      "guid VARCHAR PRIMARY KEY, "
                      "label VARCHAR, "
                      "first_name VARCHAR, "
                      "middle_name VARCHAR, "
                      "last_name VARCHAR, "
                      "email VARCHAR, "
                      "company_name VARCHAR, "
                      "address_line_1 VARCHAR, "
                      "address_line_2 VARCHAR, "
                      "city VARCHAR, "
                      "state VARCHAR, "
                      "zipcode VARCHAR, "
                      "country VARCHAR, "
                      "phone VARCHAR, "
                      "fax VARCHAR, "
                      "date_modified INTEGER NOT NULL DEFAULT 0)")) {
      return false;
    }

    if (!db_->Execute(
        "INSERT INTO autofill_profiles_temp "
        "SELECT guid, label, first_name, middle_name, last_name, email, "
        "company_name, address_line_1, address_line_2, city, state, "
        "zipcode, country, phone, fax, date_modified "
        "FROM autofill_profiles")) {
      return false;
    }

    if (!db_->Execute("DROP TABLE autofill_profiles"))
      return false;

    if (!db_->Execute(
        "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) {
      return false;
    }
  }

  if (db_->DoesColumnExist("credit_cards", "unique_id")) {
    if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
                      "guid VARCHAR PRIMARY KEY, "
                      "label VARCHAR, "
                      "name_on_card VARCHAR, "
                      "expiration_month INTEGER, "
                      "expiration_year INTEGER, "
                      "card_number_encrypted BLOB, "
                      "date_modified INTEGER NOT NULL DEFAULT 0)")) {
      return false;
    }

    if (!db_->Execute(
        "INSERT INTO credit_cards_temp "
        "SELECT guid, label, name_on_card, expiration_month, "
        "expiration_year, card_number_encrypted, date_modified "
        "FROM credit_cards")) {
      return false;
    }

    if (!db_->Execute("DROP TABLE credit_cards"))
      return false;

    if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
      return false;
  }

  return true;
}

// Test the existence of the |first_name| column as an indication that
// we need a migration.  It is possible that the new |autofill_profiles|
// schema is in place because the table was newly created when migrating
// from a pre-version-22 database.
bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() {
  if (db_->DoesColumnExist("autofill_profiles", "first_name")) {
    // Create autofill_profiles_temp table that will receive the data.
    if (!db_->DoesTableExist("autofill_profiles_temp")) {
      if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( "
                        "guid VARCHAR PRIMARY KEY, "
                        "company_name VARCHAR, "
                        "address_line_1 VARCHAR, "
                        "address_line_2 VARCHAR, "
                        "city VARCHAR, "
                        "state VARCHAR, "
                        "zipcode VARCHAR, "
                        "country VARCHAR, "
                        "date_modified INTEGER NOT NULL DEFAULT 0)")) {
        return false;
      }
    }

    sql::Statement s(db_->GetUniqueStatement(
        "SELECT guid, first_name, middle_name, last_name, email, "
        "company_name, address_line_1, address_line_2, city, state, "
        "zipcode, country, phone, fax, date_modified "
        "FROM autofill_profiles"));
    while (s.Step()) {
      AutofillProfile profile;
      profile.set_guid(s.ColumnString(0));
      DCHECK(guid::IsValidGUID(profile.guid()));

      profile.SetInfo(NAME_FIRST, s.ColumnString16(1));
      profile.SetInfo(NAME_MIDDLE, s.ColumnString16(2));
      profile.SetInfo(NAME_LAST, s.ColumnString16(3));
      profile.SetInfo(EMAIL_ADDRESS, s.ColumnString16(4));
      profile.SetInfo(COMPANY_NAME, s.ColumnString16(5));
      profile.SetInfo(ADDRESS_HOME_LINE1, s.ColumnString16(6));
      profile.SetInfo(ADDRESS_HOME_LINE2, s.ColumnString16(7));
      profile.SetInfo(ADDRESS_HOME_CITY, s.ColumnString16(8));
      profile.SetInfo(ADDRESS_HOME_STATE, s.ColumnString16(9));
      profile.SetInfo(ADDRESS_HOME_ZIP, s.ColumnString16(10));
      profile.SetInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(11));
      profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(12));
      profile.SetInfo(PHONE_FAX_WHOLE_NUMBER, s.ColumnString16(13));
      int64 date_modified = s.ColumnInt64(14);

      sql::Statement s_insert(db_->GetUniqueStatement(
          "INSERT INTO autofill_profiles_temp"
          "(guid, company_name, address_line_1, address_line_2, city,"
          " state, zipcode, country, date_modified)"
          "VALUES (?,?,?,?,?,?,?,?,?)"));
      if (!s)
        return false;

      s_insert.BindString(0, profile.guid());
      s_insert.BindString16(1, profile.GetInfo(COMPANY_NAME));
      s_insert.BindString16(2, profile.GetInfo(ADDRESS_HOME_LINE1));
      s_insert.BindString16(3, profile.GetInfo(ADDRESS_HOME_LINE2));
      s_insert.BindString16(4, profile.GetInfo(ADDRESS_HOME_CITY));
      s_insert.BindString16(5, profile.GetInfo(ADDRESS_HOME_STATE));
      s_insert.BindString16(6, profile.GetInfo(ADDRESS_HOME_ZIP));
      s_insert.BindString16(7, profile.GetInfo(ADDRESS_HOME_COUNTRY));
      s_insert.BindInt64(8, date_modified);

      if (!s_insert.Run())
        return false;

      // Add the other bits: names, emails, and phone/fax.
      if (!AddAutofillProfilePieces(profile, db_))
        return false;
    }

    if (!db_->Execute("DROP TABLE autofill_profiles"))
      return false;

    if (!db_->Execute(
        "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) {
      return false;
    }
  }

  // Remove the labels column from the credit_cards table.
  if (db_->DoesColumnExist("credit_cards", "label")) {
    if (!db_->Execute("CREATE TABLE credit_cards_temp ( "
                      "guid VARCHAR PRIMARY KEY, "
                      "name_on_card VARCHAR, "
                      "expiration_month INTEGER, "
                      "expiration_year INTEGER, "
                      "card_number_encrypted BLOB, "
                      "date_modified INTEGER NOT NULL DEFAULT 0)")) {
      return false;
    }

    if (!db_->Execute(
        "INSERT INTO credit_cards_temp "
        "SELECT guid, name_on_card, expiration_month, "
        "expiration_year, card_number_encrypted, date_modified "
        "FROM credit_cards")) {
      return false;
    }

    if (!db_->Execute("DROP TABLE credit_cards"))
      return false;

    if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards"))
      return false;
  }

  return true;
}

// Test the existence of the |country_code| column as an indication that
// we need a migration.  It is possible that the new |autofill_profiles|
// schema is in place because the table was newly created when migrating
// from a pre-version-22 database.
bool AutofillTable::MigrateToVersion34ProfilesBasedOnCountryCode() {
  if (!db_->DoesColumnExist("autofill_profiles", "country_code")) {
    if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN "
                      "country_code VARCHAR")) {
      return false;
    }

    // Set all the |country_code| fields to match existing |country| values.
    sql::Statement s(db_->GetUniqueStatement("SELECT guid, country "
                                             "FROM autofill_profiles"));

    if (!s)
      return false;

    while (s.Step()) {
      sql::Statement update_s(
          db_->GetUniqueStatement("UPDATE autofill_profiles "
                                  "SET country_code=? WHERE guid=?"));
      if (!update_s)
        return false;

      string16 country = s.ColumnString16(1);
      std::string app_locale = AutofillCountry::ApplicationLocale();
      update_s.BindString(0, AutofillCountry::GetCountryCode(country,
                                                             app_locale));
      update_s.BindString(1, s.ColumnString(0));

      if (!update_s.Run())
        return false;
    }
  }

  return true;
}

// Correct all country codes with value "UK" to be "GB".  This data
// was mistakenly introduced in build 686.0.  This migration is to clean
// it up.  See http://crbug.com/74511 for details.
bool AutofillTable::MigrateToVersion35GreatBritainCountryCodes() {
  sql::Statement s(db_->GetUniqueStatement(
      "UPDATE autofill_profiles SET country_code=\"GB\" "
      "WHERE country_code=\"UK\""));

  return s.Run();
}

// Merge and cull older profiles where possible.
bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() {
  sql::Statement s(db_->GetUniqueStatement(
      "SELECT guid, date_modified FROM autofill_profiles"));
  if (!s)
    return false;

  // Accumulate the good profiles.
  std::vector<AutofillProfile> accumulated_profiles;
  std::vector<AutofillProfile*> accumulated_profiles_p;
  std::map<std::string, int64> modification_map;
  while (s.Step()) {
    std::string guid = s.ColumnString(0);
    int64 date_modified = s.ColumnInt64(1);
    modification_map.insert(
        std::pair<std::string, int64>(guid, date_modified));
    AutofillProfile* profile = NULL;
    if (!GetAutofillProfile(guid, &profile))
      return false;

    scoped_ptr<AutofillProfile> p(profile);

    if (PersonalDataManager::IsValidLearnableProfile(*p)) {
      std::vector<AutofillProfile> merged_profiles;
      bool merged = PersonalDataManager::MergeProfile(
          *p, accumulated_profiles_p, &merged_profiles);

      std::swap(accumulated_profiles, merged_profiles);

      accumulated_profiles_p.clear();
      accumulated_profiles_p.resize(accumulated_profiles.size());
      std::transform(accumulated_profiles.begin(),
                     accumulated_profiles.end(),
                     accumulated_profiles_p.begin(),
                     address_of<AutofillProfile>);

      // If the profile got merged trash the original.
      if (merged)
        AddAutofillGUIDToTrash(p->guid());

    } else {
      // An invalid profile, so trash it.
      AddAutofillGUIDToTrash(p->guid());
    }
  }

  // Drop the current profiles.
  if (!ClearAutofillProfiles())
    return false;

  // Add the newly merged profiles back in.
  for (std::vector<AutofillProfile>::const_iterator
          iter = accumulated_profiles.begin();
       iter != accumulated_profiles.end();
       ++iter) {
    if (!AddAutofillProfile(*iter))
      return false;

    // Fix up the original modification date.
    std::map<std::string, int64>::const_iterator date_item =
        modification_map.find(iter->guid());
    if (date_item == modification_map.end())
      return false;

    sql::Statement s_date(db_->GetUniqueStatement(
        "UPDATE autofill_profiles SET date_modified=? "
        "WHERE guid=?"));
    s_date.BindInt64(0, date_item->second);
    s_date.BindString(1, iter->guid());
    if (!s_date.Run())
      return false;
  }

  return true;
}
