// 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/diagnostics/sqlite_diagnostics.h"

#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/common/content_constants.h"
#include "sql/connection.h"
#include "sql/diagnostic_error_delegate.h"
#include "sql/statement.h"
#include "third_party/sqlite/sqlite3.h"
#include "webkit/appcache/appcache_interfaces.h"
#include "webkit/database/database_tracker.h"

namespace {

// Generic diagnostic test class for checking sqlite db integrity.
class SqliteIntegrityTest : public DiagnosticTest {
 public:
  SqliteIntegrityTest(bool critical, const string16& title,
                      const FilePath& profile_relative_db_path)
      : DiagnosticTest(title),
        critical_(critical),
        db_path_(profile_relative_db_path) {
  }

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    FilePath path = GetUserDefaultProfileDir();
    path = path.Append(db_path_);
    if (!file_util::PathExists(path)) {
      RecordOutcome(ASCIIToUTF16("File not found"),
                    critical_ ? DiagnosticsModel::TEST_FAIL_CONTINUE :
                                DiagnosticsModel::TEST_OK);
      return true;
    }

    int errors = 0;
    { // This block scopes the lifetime of the db objects.
      sql::Connection db;
      db.set_exclusive_locking();
      if (!db.Open(path)) {
        RecordFailure(ASCIIToUTF16("Cannot open DB. Possibly corrupted"));
        return true;
      }
      sql::Statement s(db.GetUniqueStatement("PRAGMA integrity_check;"));
      if (!s.is_valid()) {
        int error = db.GetErrorCode();
        if (SQLITE_BUSY == error) {
          RecordFailure(ASCIIToUTF16("DB locked by another process"));
        } else {
          string16 str(ASCIIToUTF16("Pragma failed. Error: "));
          str += base::IntToString16(error);
          RecordFailure(str);
        }
        return false;
      }
      while (s.Step()) {
        std::string result(s.ColumnString(0));
        if ("ok" != result)
          ++errors;
      }
    }
    // All done. Report to the user.
    if (errors != 0) {
      string16 str(ASCIIToUTF16("Database corruption detected :"));
      str += base::IntToString16(errors) + ASCIIToUTF16(" errors");
      RecordFailure(str);
      return true;
    }
    RecordSuccess(ASCIIToUTF16("no corruption detected"));
    return true;
  }

 private:
  bool critical_;
  FilePath db_path_;
  DISALLOW_COPY_AND_ASSIGN(SqliteIntegrityTest);
};

// Uniquifier to use the sql::DiagnosticErrorDelegate template which
// requires a static name() method.
template <size_t unique>
class HistogramUniquifier {
 public:
  static const char* name() {
    const char* kHistogramNames[] = {
      "Sqlite.Cookie.Error",
      "Sqlite.History.Error",
      "Sqlite.Thumbnail.Error",
      "Sqlite.Text.Error",
      "Sqlite.Web.Error"
    };
    return kHistogramNames[unique];
  }
};

}  // namespace

sql::ErrorDelegate* GetErrorHandlerForCookieDb() {
  return new sql::DiagnosticErrorDelegate<HistogramUniquifier<0> >();
}

sql::ErrorDelegate* GetErrorHandlerForHistoryDb() {
  return new sql::DiagnosticErrorDelegate<HistogramUniquifier<1> >();
}

sql::ErrorDelegate* GetErrorHandlerForThumbnailDb() {
  return new sql::DiagnosticErrorDelegate<HistogramUniquifier<2> >();
}

sql::ErrorDelegate* GetErrorHandlerForTextDb() {
  return new sql::DiagnosticErrorDelegate<HistogramUniquifier<3> >();
}

sql::ErrorDelegate* GetErrorHandlerForWebDb() {
  return new sql::DiagnosticErrorDelegate<HistogramUniquifier<4> >();
}

DiagnosticTest* MakeSqliteWebDbTest() {
  return new SqliteIntegrityTest(true, ASCIIToUTF16("Web DB"),
                                 FilePath(chrome::kWebDataFilename));
}

DiagnosticTest* MakeSqliteCookiesDbTest() {
  return new SqliteIntegrityTest(true, ASCIIToUTF16("Cookies DB"),
                                 FilePath(chrome::kCookieFilename));
}

DiagnosticTest* MakeSqliteHistoryDbTest() {
  return new SqliteIntegrityTest(true, ASCIIToUTF16("History DB"),
                                 FilePath(chrome::kHistoryFilename));
}

DiagnosticTest* MakeSqliteArchivedHistoryDbTest() {
  return new SqliteIntegrityTest(false, ASCIIToUTF16("Archived History DB"),
                                 FilePath(chrome::kArchivedHistoryFilename));
}

DiagnosticTest* MakeSqliteThumbnailsDbTest() {
  return new SqliteIntegrityTest(false, ASCIIToUTF16("Thumbnails DB"),
                                 FilePath(chrome::kThumbnailsFilename));
}

DiagnosticTest* MakeSqliteAppCacheDbTest() {
  FilePath appcache_dir(content::kAppCacheDirname);
  FilePath appcache_db = appcache_dir.Append(appcache::kAppCacheDatabaseName);
  return new SqliteIntegrityTest(false, ASCIIToUTF16("AppCache DB"),
                                 appcache_db);
}

DiagnosticTest* MakeSqliteWebDatabaseTrackerDbTest() {
  FilePath databases_dir(webkit_database::kDatabaseDirectoryName);
  FilePath tracker_db =
      databases_dir.Append(webkit_database::kTrackerDatabaseFileName);
  return new SqliteIntegrityTest(false, ASCIIToUTF16("DatabaseTracker DB"),
                                 tracker_db);
}
