// 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) {
  base::Time maximum_expiry = base::Time::Now() + kMaxCookieLifetime;

  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()) {
    base::Time expiry = base::Time::FromInternalValue(get_all.ColumnInt64(8));
    if (expiry > maximum_expiry) {
      expiry = maximum_expiry;
    }

    net::CanonicalCookie* cookie = net::CanonicalCookie::Create(
        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)), expiry,
        get_all.ColumnBool(10), get_all.ColumnBool(11));
    if (cookie) {
      cookie->SetLastAccessDate(
          base::Time::FromInternalValue(get_all.ColumnInt64(9)));
      actual_cookies.push_back(cookie);
    } else {
      DLOG(ERROR) << "Failed to create 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
