// Copyright 2016 The Cobalt Authors. 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 <cstring>

#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/files/platform_file.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/time/time.h"
#include "cobalt/storage/upgrade/upgrade_reader.h"
#include "net/cookies/canonical_cookie.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace cobalt {
namespace storage {
namespace upgrade {

namespace {

using ::testing::StrictMock;

class MockUpgradeReader : public UpgradeReader {
 public:
  MOCK_METHOD0(OnNullExpiration, void());
};

void ReadFileToString(const char* pathname, std::string* string_out) {
  EXPECT_TRUE(pathname);
  EXPECT_TRUE(string_out);
  base::FilePath file_path;
  EXPECT_TRUE(base::PathService::Get(base::DIR_TEST_DATA, &file_path));
  file_path = file_path.Append(pathname);
  EXPECT_TRUE(base::ReadFileToString(file_path, string_out));
  const char* data = string_out->c_str();
  const int size = static_cast<int>(string_out->length());
  EXPECT_GT(size, 0);
  EXPECT_LE(size, 10 * 1024 * 1024);
  EXPECT_TRUE(UpgradeReader::IsUpgradeData(data, size));
}

void ValidateCookie(const net::CanonicalCookie* cookie,
                    const std::string& /*url*/, const std::string& name,
                    const std::string& value, const std::string domain,
                    const std::string& path, const base::Time& creation,
                    const base::Time expiration, bool http_only) {
  EXPECT_TRUE(cookie);
  EXPECT_EQ(cookie->Name(), name);
  EXPECT_EQ(cookie->Value(), value);
  EXPECT_EQ(cookie->Domain(), domain);
  EXPECT_EQ(cookie->Path(), path);
  EXPECT_EQ((cookie->CreationDate() - creation).InSeconds(), 0);
  EXPECT_EQ((cookie->ExpiryDate() - expiration).InSeconds(), 0);
  EXPECT_EQ((cookie->LastAccessDate() - base::Time::Now()).InSeconds(), 0);
  EXPECT_EQ(cookie->IsSecure(), true);
  EXPECT_EQ(cookie->IsHttpOnly(), http_only);
}

void ValidateCookie(const net::CanonicalCookie* cookie, const std::string& url,
                    const std::string& name, const std::string& value) {
  const std::string host = GURL(url).host();
  const std::string domain = host.empty() ? "" : host.substr(host.find("."));
  const std::string path = "/";
  const base::Time creation = base::Time::Now();
  const base::Time expiration = base::Time();
  const bool http_only = false;
  ValidateCookie(cookie, url, name, value, domain, path, creation, expiration,
                 http_only);
}

void ValidateLocalStorageEntry(
    const UpgradeReader::LocalStorageEntry* local_storage_entry,
    const std::string& key, const std::string& value) {
  EXPECT_TRUE(local_storage_entry);
  EXPECT_EQ(local_storage_entry->key, key);
  EXPECT_EQ(local_storage_entry->value, value);
}

}  // namespace

TEST(StorageUpgradeTest, UpgradeMinimalCookie) {
  std::string file_contents;
  ReadFileToString("cobalt/storage/upgrade/testdata/minimal_cookie_v1.json",
                   &file_contents);
  StrictMock<MockUpgradeReader> upgrade_reader;

  // No expiration
  EXPECT_CALL(upgrade_reader, OnNullExpiration());

  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // 1 cookie.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 1);
  const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
  ValidateCookie(cookie, "https://www.example.com/", "cookie_name",
                 "cookie_value");
  EXPECT_FALSE(upgrade_reader.GetCookie(1));

  // 0 local storage entries.
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 0);
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(0));
}

TEST(StorageUpgradeTest, UpgradeMinimalLocalStorageEntry) {
  std::string file_contents;
  ReadFileToString(
      "cobalt/storage/upgrade/testdata/minimal_local_storage_entry_v1.json",
      &file_contents);
  UpgradeReader upgrade_reader;
  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // 0 cookies.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
  EXPECT_FALSE(upgrade_reader.GetCookie(0));

  // 1 local storage entry.
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 1);
  const UpgradeReader::LocalStorageEntry* local_storage_entry =
      upgrade_reader.GetLocalStorageEntry(0);
  ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(1));
}

TEST(StorageUpgradeTest, UpgradeFullData) {
  std::string file_contents;
  ReadFileToString("cobalt/storage/upgrade/testdata/full_data_v1.json",
                   &file_contents);
  UpgradeReader upgrade_reader;
  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // 2 cookies.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 2);
  const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
  base::Time creation = base::Time::FromInternalValue(13119668760000000L);
  base::Time expiration = base::Time::FromInternalValue(13120000000000000L);
  ValidateCookie(cookie, "https://www.example.com/1", "cookie_name",
                 "cookie_value", ".example.com", "/1", creation, expiration,
                 true);
  cookie = upgrade_reader.GetCookie(1);
  creation = base::Time::FromInternalValue(13109668760000000L);
  expiration = base::Time::FromInternalValue(13110000000000000L);
  ValidateCookie(cookie, "https://www.somewhere.com/2", "cookie_name_2",
                 "cookie_value_2", ".somewhere.com", "/2", creation, expiration,
                 true);
  EXPECT_FALSE(upgrade_reader.GetCookie(2));

  // 2 local storage entries.
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 2);
  const UpgradeReader::LocalStorageEntry* local_storage_entry =
      upgrade_reader.GetLocalStorageEntry(0);
  ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
  local_storage_entry = upgrade_reader.GetLocalStorageEntry(1);
  ValidateLocalStorageEntry(local_storage_entry, "key-2", "value-2");
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(2));
}

TEST(StorageUpgradeTest, UpgradeMissingFields) {
  std::string file_contents;
  ReadFileToString("cobalt/storage/upgrade/testdata/missing_fields_v1.json",
                   &file_contents);
  UpgradeReader upgrade_reader;
  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // 1 cookie with missing fields, 2 local storage entries with missing fields,
  // 1 valid local storage entry.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
  EXPECT_FALSE(upgrade_reader.GetCookie(0));
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 1);
  const UpgradeReader::LocalStorageEntry* local_storage_entry =
      upgrade_reader.GetLocalStorageEntry(0);
  ValidateLocalStorageEntry(local_storage_entry, "key-3", "value-3");
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(1));
}

TEST(StorageUpgradeTest, UpgradeMalformed) {
  std::string file_contents;
  ReadFileToString("cobalt/storage/upgrade/testdata/malformed_v1.json",
                   &file_contents);
  UpgradeReader upgrade_reader;
  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // No cookies or local storage entries available in malformed data.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
  EXPECT_FALSE(upgrade_reader.GetCookie(0));
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 0);
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(0));
}

TEST(StorageUpgradeTest, UpgradeExtraFields) {
  std::string file_contents;
  ReadFileToString("cobalt/storage/upgrade/testdata/extra_fields_v1.json",
                   &file_contents);
  StrictMock<MockUpgradeReader> upgrade_reader;

  // No expiration
  EXPECT_CALL(upgrade_reader, OnNullExpiration());

  upgrade_reader.Parse(file_contents.c_str(),
                       static_cast<int>(file_contents.length()));

  // 1 cookie, extra fields should be ignored.
  EXPECT_EQ(upgrade_reader.GetNumCookies(), 1);
  const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
  ValidateCookie(cookie, "https://www.example.com/", "cookie_name",
                 "cookie_value");
  EXPECT_FALSE(upgrade_reader.GetCookie(1));

  // 2 local storage entries, extra fields should be ignored.
  EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 2);
  const UpgradeReader::LocalStorageEntry* local_storage_entry =
      upgrade_reader.GetLocalStorageEntry(0);
  ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
  local_storage_entry = upgrade_reader.GetLocalStorageEntry(1);
  ValidateLocalStorageEntry(local_storage_entry, "key-2", "value-2");
  EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(2));
}

}  // namespace upgrade
}  // namespace storage
}  // namespace cobalt
