// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/media/webrtc_identity_store_backend.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "sql/error_delegate_util.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "url/gurl.h"
#include "webkit/browser/quota/special_storage_policy.h"

namespace content {

static const char* kWebRTCIdentityStoreDBName = "webrtc_identity_store";

static const base::FilePath::CharType kWebRTCIdentityStoreDirectory[] =
    FILE_PATH_LITERAL("WebRTCIdentityStore");

// Initializes the identity table, returning true on success.
static bool InitDB(sql::Connection* db) {
  if (db->DoesTableExist(kWebRTCIdentityStoreDBName)) {
    if (db->DoesColumnExist(kWebRTCIdentityStoreDBName, "origin") &&
        db->DoesColumnExist(kWebRTCIdentityStoreDBName, "identity_name") &&
        db->DoesColumnExist(kWebRTCIdentityStoreDBName, "common_name") &&
        db->DoesColumnExist(kWebRTCIdentityStoreDBName, "certificate") &&
        db->DoesColumnExist(kWebRTCIdentityStoreDBName, "private_key") &&
        db->DoesColumnExist(kWebRTCIdentityStoreDBName, "creation_time"))
      return true;
    if (!db->Execute("DROP TABLE webrtc_identity_store"))
      return false;
  }

  return db->Execute(
      "CREATE TABLE webrtc_identity_store"
      " ("
      "origin TEXT NOT NULL,"
      "identity_name TEXT NOT NULL,"
      "common_name TEXT NOT NULL,"
      "certificate BLOB NOT NULL,"
      "private_key BLOB NOT NULL,"
      "creation_time INTEGER)");
}

struct WebRTCIdentityStoreBackend::IdentityKey {
  IdentityKey(const GURL& origin, const std::string& identity_name)
      : origin(origin), identity_name(identity_name) {}

  bool operator<(const IdentityKey& other) const {
    return origin < other.origin ||
           (origin == other.origin && identity_name < other.identity_name);
  }

  GURL origin;
  std::string identity_name;
};

struct WebRTCIdentityStoreBackend::Identity {
  Identity(const std::string& common_name,
           const std::string& certificate,
           const std::string& private_key)
      : common_name(common_name),
        certificate(certificate),
        private_key(private_key),
        creation_time(base::Time::Now().ToInternalValue()) {}

  Identity(const std::string& common_name,
           const std::string& certificate,
           const std::string& private_key,
           int64 creation_time)
      : common_name(common_name),
        certificate(certificate),
        private_key(private_key),
        creation_time(creation_time) {}

  std::string common_name;
  std::string certificate;
  std::string private_key;
  int64 creation_time;
};

struct WebRTCIdentityStoreBackend::PendingFindRequest {
  PendingFindRequest(const GURL& origin,
                     const std::string& identity_name,
                     const std::string& common_name,
                     const FindIdentityCallback& callback)
      : origin(origin),
        identity_name(identity_name),
        common_name(common_name),
        callback(callback) {}

  ~PendingFindRequest() {}

  GURL origin;
  std::string identity_name;
  std::string common_name;
  FindIdentityCallback callback;
};

// The class encapsulates the database operations. All members except ctor and
// dtor should be accessed on the DB thread.
// It can be created/destroyed on any thread.
class WebRTCIdentityStoreBackend::SqlLiteStorage
    : public base::RefCountedThreadSafe<SqlLiteStorage> {
 public:
  SqlLiteStorage(const base::FilePath& path,
                 quota::SpecialStoragePolicy* policy)
      : special_storage_policy_(policy) {
    if (!path.empty())
      path_ = path.Append(kWebRTCIdentityStoreDirectory);
  }

  void Load(IdentityMap* out_map);
  void Close();
  void AddIdentity(const GURL& origin,
                   const std::string& identity_name,
                   const Identity& identity);
  void DeleteIdentity(const GURL& origin,
                      const std::string& identity_name,
                      const Identity& identity);
  void DeleteBetween(base::Time delete_begin,
                     base::Time delete_end,
                     const base::Closure& callback);

 private:
  friend class base::RefCountedThreadSafe<SqlLiteStorage>;

  enum OperationType {
    ADD_IDENTITY,
    DELETE_IDENTITY
  };
  struct PendingOperation {
    PendingOperation(OperationType type,
                     const GURL& origin,
                     const std::string& identity_name,
                     const Identity& identity)
        : type(type),
          origin(origin),
          identity_name(identity_name),
          identity(identity) {}

    OperationType type;
    GURL origin;
    std::string identity_name;
    Identity identity;
  };
  typedef std::vector<PendingOperation*> PendingOperationList;

  virtual ~SqlLiteStorage() {}
  void OnDatabaseError(int error, sql::Statement* stmt);
  void BatchOperation(OperationType type,
                      const GURL& origin,
                      const std::string& identity_name,
                      const Identity& identity);
  void Commit();

  // The file path of the DB. Empty if temporary.
  base::FilePath path_;
  scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
  scoped_ptr<sql::Connection> db_;
  // Batched DB operations pending to commit.
  PendingOperationList pending_operations_;

  DISALLOW_COPY_AND_ASSIGN(SqlLiteStorage);
};

WebRTCIdentityStoreBackend::WebRTCIdentityStoreBackend(
    const base::FilePath& path,
    quota::SpecialStoragePolicy* policy)
    : state_(NOT_STARTED),
      sql_lite_storage_(new SqlLiteStorage(path, policy)) {}

bool WebRTCIdentityStoreBackend::FindIdentity(
    const GURL& origin,
    const std::string& identity_name,
    const std::string& common_name,
    const FindIdentityCallback& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  if (state_ == CLOSED)
    return false;

  if (state_ != LOADED) {
    // Queues the request to wait for the DB to load.
    pending_find_requests_.push_back(
        new PendingFindRequest(origin, identity_name, common_name, callback));
    if (state_ == LOADING)
      return true;

    DCHECK_EQ(state_, NOT_STARTED);

    // Kick off loading the DB.
    scoped_ptr<IdentityMap> out_map(new IdentityMap());
    if (BrowserThread::PostTaskAndReply(
            BrowserThread::DB,
            FROM_HERE,
            base::Bind(&SqlLiteStorage::Load, sql_lite_storage_, out_map.get()),
            base::Bind(&WebRTCIdentityStoreBackend::OnLoaded,
                       this,
                       base::Passed(&out_map)))) {
      state_ = LOADING;
      return true;
    }
    // If it fails to post task, falls back to ERR_FILE_NOT_FOUND.
  }

  IdentityKey key(origin, identity_name);
  IdentityMap::iterator iter = identities_.find(key);
  if (iter != identities_.end() && iter->second.common_name == common_name) {
    // Identity found.
    return BrowserThread::PostTask(BrowserThread::IO,
                                   FROM_HERE,
                                   base::Bind(callback,
                                              net::OK,
                                              iter->second.certificate,
                                              iter->second.private_key));
  }

  return BrowserThread::PostTask(
      BrowserThread::IO,
      FROM_HERE,
      base::Bind(callback, net::ERR_FILE_NOT_FOUND, "", ""));
}

void WebRTCIdentityStoreBackend::AddIdentity(const GURL& origin,
                                             const std::string& identity_name,
                                             const std::string& common_name,
                                             const std::string& certificate,
                                             const std::string& private_key) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  if (state_ == CLOSED)
    return;

  // If there is an existing identity for the same origin and identity_name,
  // delete it.
  IdentityKey key(origin, identity_name);
  Identity identity(common_name, certificate, private_key);

  if (identities_.find(key) != identities_.end()) {
    if (!BrowserThread::PostTask(BrowserThread::DB,
                                 FROM_HERE,
                                 base::Bind(&SqlLiteStorage::DeleteIdentity,
                                            sql_lite_storage_,
                                            origin,
                                            identity_name,
                                            identities_.find(key)->second)))
      return;
  }
  identities_.insert(std::pair<IdentityKey, Identity>(key, identity));

  BrowserThread::PostTask(BrowserThread::DB,
                          FROM_HERE,
                          base::Bind(&SqlLiteStorage::AddIdentity,
                                     sql_lite_storage_,
                                     origin,
                                     identity_name,
                                     identity));
}

void WebRTCIdentityStoreBackend::Close() {
  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
    BrowserThread::PostTask(
        BrowserThread::IO,
        FROM_HERE,
        base::Bind(&WebRTCIdentityStoreBackend::Close, this));
    return;
  }

  if (state_ == CLOSED)
    return;

  state_ = CLOSED;
  BrowserThread::PostTask(
      BrowserThread::DB,
      FROM_HERE,
      base::Bind(&SqlLiteStorage::Close, sql_lite_storage_));
}

void WebRTCIdentityStoreBackend::DeleteBetween(base::Time delete_begin,
                                               base::Time delete_end,
                                               const base::Closure& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  // Delete the in-memory cache.
  IdentityMap::iterator it = identities_.begin();
  while (it != identities_.end()) {
    if (it->second.creation_time >= delete_begin.ToInternalValue() &&
        it->second.creation_time <= delete_end.ToInternalValue())
      identities_.erase(it++);
    else
      it++;
  }

  BrowserThread::PostTaskAndReply(BrowserThread::DB,
                                  FROM_HERE,
                                  base::Bind(&SqlLiteStorage::DeleteBetween,
                                             sql_lite_storage_,
                                             delete_begin,
                                             delete_end,
                                             callback),
                                  callback);
}

WebRTCIdentityStoreBackend::~WebRTCIdentityStoreBackend() {}

void WebRTCIdentityStoreBackend::OnLoaded(scoped_ptr<IdentityMap> out_map) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  state_ = LOADED;
  identities_.swap(*out_map);

  for (size_t i = 0; i < pending_find_requests_.size(); ++i) {
    FindIdentity(pending_find_requests_[i]->origin,
                 pending_find_requests_[i]->identity_name,
                 pending_find_requests_[i]->common_name,
                 pending_find_requests_[i]->callback);
    delete pending_find_requests_[i];
  }
  pending_find_requests_.clear();
}

//
// Implementation of SqlLiteStorage.
//

void WebRTCIdentityStoreBackend::SqlLiteStorage::Load(IdentityMap* out_map) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  DCHECK(!db_.get());

  // Ensure the parent directory for storing certs is created before reading
  // from it.
  const base::FilePath dir = path_.DirName();
  if (!base::PathExists(dir) && !file_util::CreateDirectory(dir)) {
    DLOG(ERROR) << "Unable to open DB file path.";
    return;
  }

  db_.reset(new sql::Connection());

  db_->set_error_callback(base::Bind(&SqlLiteStorage::OnDatabaseError, this));

  if (!db_->Open(path_)) {
    DLOG(ERROR) << "Unable to open DB.";
    db_.reset();
    return;
  }

  if (!InitDB(db_.get())) {
    DLOG(ERROR) << "Unable to init DB.";
    db_.reset();
    return;
  }

  db_->Preload();

  // Slurp all the identities into the out_map.
  sql::Statement stmt(db_->GetUniqueStatement(
      "SELECT origin, identity_name, common_name, "
      "certificate, private_key, creation_time "
      "FROM webrtc_identity_store"));
  CHECK(stmt.is_valid());

  while (stmt.Step()) {
    IdentityKey key(GURL(stmt.ColumnString(0)), stmt.ColumnString(1));
    std::string common_name(stmt.ColumnString(2));
    std::string cert, private_key;
    stmt.ColumnBlobAsString(3, &cert);
    stmt.ColumnBlobAsString(4, &private_key);
    int64 creation_time = stmt.ColumnInt64(5);
    std::pair<IdentityMap::iterator, bool> result =
        out_map->insert(std::pair<IdentityKey, Identity>(
            key, Identity(common_name, cert, private_key, creation_time)));
    DCHECK(result.second);
  }
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::Close() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  Commit();
  db_.reset();
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::AddIdentity(
    const GURL& origin,
    const std::string& identity_name,
    const Identity& identity) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  if (!db_.get())
    return;

  // Do not add for session only origins.
  if (special_storage_policy_.get() &&
      !special_storage_policy_->IsStorageProtected(origin) &&
      special_storage_policy_->IsStorageSessionOnly(origin)) {
    return;
  }
  BatchOperation(ADD_IDENTITY, origin, identity_name, identity);
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteIdentity(
    const GURL& origin,
    const std::string& identity_name,
    const Identity& identity) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  if (!db_.get())
    return;
  BatchOperation(DELETE_IDENTITY, origin, identity_name, identity);
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::OnDatabaseError(
    int error,
    sql::Statement* stmt) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  if (!sql::IsErrorCatastrophic(error))
    return;
  db_->RazeAndClose();
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::BatchOperation(
    OperationType type,
    const GURL& origin,
    const std::string& identity_name,
    const Identity& identity) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  // Commit every 30 seconds.
  static const base::TimeDelta kCommitInterval(
      base::TimeDelta::FromSeconds(30));
  // Commit right away if we have more than 512 outstanding operations.
  static const size_t kCommitAfterBatchSize = 512;

  // We do a full copy of the cert here, and hopefully just here.
  scoped_ptr<PendingOperation> operation(
      new PendingOperation(type, origin, identity_name, identity));

  pending_operations_.push_back(operation.release());

  if (pending_operations_.size() == 1) {
    // We've gotten our first entry for this batch, fire off the timer.
    BrowserThread::PostDelayedTask(BrowserThread::DB,
                                   FROM_HERE,
                                   base::Bind(&SqlLiteStorage::Commit, this),
                                   kCommitInterval);
  } else if (pending_operations_.size() >= kCommitAfterBatchSize) {
    // We've reached a big enough batch, fire off a commit now.
    BrowserThread::PostTask(BrowserThread::DB,
                            FROM_HERE,
                            base::Bind(&SqlLiteStorage::Commit, this));
  }
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::Commit() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  // Maybe an old timer fired or we are already Close()'ed.
  if (!db_.get() || pending_operations_.empty())
    return;

  sql::Statement add_stmt(db_->GetCachedStatement(
      SQL_FROM_HERE,
      "INSERT INTO webrtc_identity_store "
      "(origin, identity_name, common_name, certificate,"
      " private_key, creation_time) VALUES"
      " (?,?,?,?,?,?)"));

  CHECK(add_stmt.is_valid());

  sql::Statement del_stmt(db_->GetCachedStatement(
      SQL_FROM_HERE,
      "DELETE FROM webrtc_identity_store WHERE origin=? AND identity_name=?"));

  CHECK(del_stmt.is_valid());

  sql::Transaction transaction(db_.get());
  if (!transaction.Begin()) {
    DLOG(ERROR) << "Failed to begin the transaction.";
    return;
  }

  for (PendingOperationList::iterator it = pending_operations_.begin();
       it != pending_operations_.end();
       ++it) {
    scoped_ptr<PendingOperation> po(*it);
    switch (po->type) {
      case ADD_IDENTITY: {
        add_stmt.Reset(true);
        add_stmt.BindString(0, po->origin.spec());
        add_stmt.BindString(1, po->identity_name);
        add_stmt.BindString(2, po->identity.common_name);
        const std::string& cert = po->identity.certificate;
        add_stmt.BindBlob(3, cert.data(), cert.size());
        const std::string& private_key = po->identity.private_key;
        add_stmt.BindBlob(4, private_key.data(), private_key.size());
        add_stmt.BindInt64(5, po->identity.creation_time);
        CHECK(add_stmt.Run());
        break;
      }
      case DELETE_IDENTITY:
        del_stmt.Reset(true);
        del_stmt.BindString(0, po->origin.spec());
        add_stmt.BindString(1, po->identity_name);
        CHECK(del_stmt.Run());
        break;

      default:
        NOTREACHED();
        break;
    }
  }
  transaction.Commit();
  pending_operations_.clear();
}

void WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteBetween(
    base::Time delete_begin,
    base::Time delete_end,
    const base::Closure& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
  if (!db_.get())
    return;

  // Commit pending operations first.
  Commit();

  sql::Statement del_stmt(db_->GetCachedStatement(
      SQL_FROM_HERE,
      "DELETE FROM webrtc_identity_store"
      " WHERE creation_time >= ? AND creation_time <= ?"));
  CHECK(del_stmt.is_valid());

  del_stmt.BindInt64(0, delete_begin.ToInternalValue());
  del_stmt.BindInt64(1, delete_end.ToInternalValue());

  sql::Transaction transaction(db_.get());
  if (!transaction.Begin()) {
    DLOG(ERROR) << "Failed to begin the transaction.";
    return;
  }

  CHECK(del_stmt.Run());
  transaction.Commit();
}

}  // namespace content
