// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/network/persistent_cookie_store.h"

#include <vector>

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/message_loop.h"
#include "googleurl/src/gurl.h"
#include "sql/connection.h"
#include "sql/statement.h"

namespace cobalt {
namespace network {

namespace {
const int kOriginalCookieSchemaVersion = 1;
const int kLatestCookieSchemaVersion = 1;
const base::TimeDelta kMaxCookieLifetime = base::TimeDelta::FromDays(365 * 2);

std::vector<net::CanonicalCookie*> GetAllCookies(sql::Connection* conn) {
  std::vector<net::CanonicalCookie*> actual_cookies;
  sql::Statement get_all(conn->GetCachedStatement(
      SQL_FROM_HERE,
      "SELECT url, name, value, domain, path, mac_key, mac_algorithm, "
      "creation, expiration, last_access, secure, http_only "
      "FROM CookieTable"));
  while (get_all.Step()) {
    // We create a CanonicalCookie directly through its constructor instead of
    // through CanonicalCookie::Create() and its sanitization because these
    // values are just serialized from a former instance of a CanonicalCookie
    // object that *was* created through CanonicalCookie::Create().
    net::CanonicalCookie* cookie = new net::CanonicalCookie(
        GURL(get_all.ColumnString(0)), get_all.ColumnString(1),
        get_all.ColumnString(2), get_all.ColumnString(3),
        get_all.ColumnString(4), get_all.ColumnString(5),
        get_all.ColumnString(6),
        base::Time::FromInternalValue(get_all.ColumnInt64(7)),
        base::Time::FromInternalValue(get_all.ColumnInt64(8)),
        base::Time::FromInternalValue(get_all.ColumnInt64(9)),
        get_all.ColumnBool(10), get_all.ColumnBool(11));
    actual_cookies.push_back(cookie);
  }

  return actual_cookies;
}

void SqlInit(const PersistentCookieStore::LoadedCallback& loaded_callback,
             storage::SqlContext* sql_context) {
  TRACE_EVENT0("cobalt::network", "PersistentCookieStore::SqlInit()");

  sql::Connection* conn = sql_context->sql_connection();

  // Check the table's schema version.
  int schema_version;
  bool table_exists =
      sql_context->GetSchemaVersion("CookieTable", &schema_version);

  if (table_exists) {
    if (schema_version == storage::StorageManager::kSchemaTableIsNew) {
      // This savegame predates the existence of the schema table.
      // Since the cookie table did not change between the initial release of
      // the app and the introduction of the schema table, assume that this
      // existing cookie table is schema version 1.  This avoids a loss of
      // cookies on upgrade.
      DLOG(INFO) << "Updating CookieTable schema version to "
                 << kOriginalCookieSchemaVersion;
      sql_context->UpdateSchemaVersion("CookieTable",
                                       kOriginalCookieSchemaVersion);
    } else if (schema_version == storage::StorageManager::kSchemaVersionLost) {
      // Since there has only been one schema so far, treat this the same as
      // kSchemaTableIsNew.  When there are multiple schemas in the wild,
      // we may want to drop the table instead.
      sql_context->UpdateSchemaVersion("CookieTable",
                                       kOriginalCookieSchemaVersion);
    }
  } else {
    // The table does not exist, so create it in its latest form.
    sql::Statement create_table(conn->GetUniqueStatement(
        "CREATE TABLE CookieTable ("
        "url TEXT, "
        "name TEXT, "
        "value TEXT, "
        "domain TEXT, "
        "path TEXT, "
        "mac_key TEXT, "
        "mac_algorithm TEXT, "
        "creation INTEGER, "
        "expiration INTEGER, "
        "last_access INTEGER, "
        "secure INTEGER, "
        "http_only INTEGER, "
        "UNIQUE(name, domain, path) ON CONFLICT REPLACE)"));
    bool ok = create_table.Run();
    DCHECK(ok);
    sql_context->UpdateSchemaVersion("CookieTable", kLatestCookieSchemaVersion);
  }

  loaded_callback.Run(GetAllCookies(conn));
}

void SqlAddCookie(const net::CanonicalCookie& cc,
                  storage::SqlContext* sql_context) {
  base::Time maximum_expiry = base::Time::Now() + kMaxCookieLifetime;
  base::Time expiry = cc.ExpiryDate();
  if (expiry > maximum_expiry) {
    expiry = maximum_expiry;
  }
  sql::Connection* conn = sql_context->sql_connection();
  sql::Statement insert_cookie(conn->GetCachedStatement(
      SQL_FROM_HERE,
      "INSERT INTO CookieTable ("
      "url, name, value, domain, path, mac_key, mac_algorithm, "
      "creation, expiration, last_access, secure, http_only"
      ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));

  insert_cookie.BindString(0, cc.Source());
  insert_cookie.BindString(1, cc.Name());
  insert_cookie.BindString(2, cc.Value());
  insert_cookie.BindString(3, cc.Domain());
  insert_cookie.BindString(4, cc.Path());
  insert_cookie.BindString(5, cc.MACKey());
  insert_cookie.BindString(6, cc.MACAlgorithm());
  insert_cookie.BindInt64(7, cc.CreationDate().ToInternalValue());
  insert_cookie.BindInt64(8, expiry.ToInternalValue());
  insert_cookie.BindInt64(9, cc.LastAccessDate().ToInternalValue());
  insert_cookie.BindBool(10, cc.IsSecure());
  insert_cookie.BindBool(11, cc.IsHttpOnly());
  bool ok = insert_cookie.Run();
  DCHECK(ok);
  sql_context->FlushOnChange();
}

void SqlUpdateCookieAccessTime(const net::CanonicalCookie& cc,
                               storage::SqlContext* sql_context) {
  sql::Connection* conn = sql_context->sql_connection();
  sql::Statement touch_cookie(
      conn->GetCachedStatement(SQL_FROM_HERE,
                               "UPDATE CookieTable SET last_access = ? WHERE "
                               "name = ? AND domain = ? AND path = ?"));

  base::Time maximum_expiry = base::Time::Now() + kMaxCookieLifetime;
  base::Time expiry = cc.ExpiryDate();
  if (expiry > maximum_expiry) {
    expiry = maximum_expiry;
  }

  touch_cookie.BindInt64(0, expiry.ToInternalValue());
  touch_cookie.BindString(1, cc.Name());
  touch_cookie.BindString(2, cc.Domain());
  touch_cookie.BindString(3, cc.Path());
  bool ok = touch_cookie.Run();
  DCHECK(ok);
  sql_context->FlushOnChange();
}

void SqlDeleteCookie(const net::CanonicalCookie& cc,
                     storage::SqlContext* sql_context) {
  sql::Connection* conn = sql_context->sql_connection();
  sql::Statement delete_cookie(conn->GetCachedStatement(
      SQL_FROM_HERE,
      "DELETE FROM CookieTable WHERE name = ? AND domain = ? AND path = ?"));
  delete_cookie.BindString(0, cc.Name());
  delete_cookie.BindString(1, cc.Domain());
  delete_cookie.BindString(2, cc.Path());
  bool ok = delete_cookie.Run();
  DCHECK(ok);
  sql_context->FlushOnChange();
}

void SqlSendEmptyCookieList(
    const PersistentCookieStore::LoadedCallback& loaded_callback,
    storage::SqlContext* sql_context) {
  UNREFERENCED_PARAMETER(sql_context);
  std::vector<net::CanonicalCookie*> empty_cookie_list;
  loaded_callback.Run(empty_cookie_list);
}

}  // namespace

PersistentCookieStore::PersistentCookieStore(storage::StorageManager* storage)
    : storage_(storage) {}

PersistentCookieStore::~PersistentCookieStore() {}

void PersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
  storage_->GetSqlContext(base::Bind(&SqlInit, loaded_callback));
}

void PersistentCookieStore::LoadCookiesForKey(
    const std::string& key, const LoadedCallback& loaded_callback) {
  UNREFERENCED_PARAMETER(key);
  // We don't support loading of individual cookies.
  // This is always called after Load(), so just post the callback to the SQL
  // thread to make sure it is run after Load() has finished.
  // See comments in net/cookie_monster.cc for more information.
  storage_->GetSqlContext(base::Bind(&SqlSendEmptyCookieList,
                                     loaded_callback));
}

void PersistentCookieStore::AddCookie(const net::CanonicalCookie& cc) {
  // We expect that all cookies we are fed are meant to persist.
  DCHECK(cc.IsPersistent());
  storage_->GetSqlContext(base::Bind(&SqlAddCookie, cc));
}

void PersistentCookieStore::UpdateCookieAccessTime(
    const net::CanonicalCookie& cc) {
  storage_->GetSqlContext(base::Bind(&SqlUpdateCookieAccessTime, cc));
}

void PersistentCookieStore::DeleteCookie(const net::CanonicalCookie& cc) {
  storage_->GetSqlContext(base::Bind(&SqlDeleteCookie, cc));
}

void PersistentCookieStore::SetForceKeepSessionState() {
  // We don't expect this to be called, and we don't implement these semantics.
  NOTREACHED();
}

void PersistentCookieStore::Flush(const base::Closure& callback) {
  storage_->FlushNow(callback);
}

}  // namespace network
}  // namespace cobalt
