// Copyright 2015 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 <stddef.h>

#include <vector>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "chrome/browser/importer/external_process_importer_host.h"
#include "chrome/browser/importer/importer_progress_observer.h"
#include "chrome/browser/importer/importer_unittest_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/importer/edge_importer_utils_win.h"
#include "chrome/common/importer/imported_bookmark_entry.h"
#include "chrome/common/importer/importer_bridge.h"
#include "chrome/common/importer/importer_data_types.h"
#include "chrome/common/importer/importer_test_registry_overrider_win.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "components/favicon_base/favicon_usage_data.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/google/compression_utils.h"

namespace {

struct FaviconGroup {
  const base::char16* favicon_url;
  const base::char16* site_url;
};

class TestObserver : public ProfileWriter,
                     public importer::ImporterProgressObserver {
 public:
  explicit TestObserver(
      const std::vector<BookmarkInfo>& expected_bookmark_entries,
      const std::vector<FaviconGroup>& expected_favicon_groups)
      : ProfileWriter(nullptr),
        bookmark_count_(0),
        expected_bookmark_entries_(expected_bookmark_entries),
        expected_favicon_groups_(expected_favicon_groups),
        favicon_count_(0) {}

  // importer::ImporterProgressObserver:
  void ImportStarted() override {}
  void ImportItemStarted(importer::ImportItem item) override {}
  void ImportItemEnded(importer::ImportItem item) override {}
  void ImportEnded() override {
    base::RunLoop::QuitCurrentWhenIdleDeprecated();
    EXPECT_EQ(expected_bookmark_entries_.size(), bookmark_count_);
    EXPECT_EQ(expected_favicon_groups_.size(), favicon_count_);
  }

  // ProfileWriter:
  bool BookmarkModelIsLoaded() const override {
    // Profile is ready for writing.
    return true;
  }

  bool TemplateURLServiceIsLoaded() const override { return true; }

  void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks,
                    const base::string16& top_level_folder_name) override {
    ASSERT_EQ(expected_bookmark_entries_.size(), bookmarks.size());
    for (size_t i = 0; i < bookmarks.size(); ++i) {
      EXPECT_NO_FATAL_FAILURE(
          TestEqualBookmarkEntry(bookmarks[i], expected_bookmark_entries_[i]))
          << i;
      ++bookmark_count_;
    }
  }

  void AddFavicons(const favicon_base::FaviconUsageDataList& usage) override {
    // Importer should group the favicon information for each favicon URL.
    ASSERT_EQ(expected_favicon_groups_.size(), usage.size());
    for (size_t i = 0; i < expected_favicon_groups_.size(); ++i) {
      GURL favicon_url(expected_favicon_groups_[i].favicon_url);
      std::set<GURL> urls;
      urls.insert(GURL(expected_favicon_groups_[i].site_url));

      bool expected_favicon_url_found = false;
      for (size_t j = 0; j < usage.size(); ++j) {
        if (usage[j].favicon_url == favicon_url) {
          EXPECT_EQ(urls, usage[j].urls);
          expected_favicon_url_found = true;
          break;
        }
      }
      EXPECT_TRUE(expected_favicon_url_found);
    }
    favicon_count_ += usage.size();
  }

 private:
  ~TestObserver() override {}

  // This is the count of bookmark entries observed during the test.
  size_t bookmark_count_;
  // This is the expected list of bookmark entries to observe during the test.
  std::vector<BookmarkInfo> expected_bookmark_entries_;
  // This is the expected list of favicon groups to observe during the test.
  std::vector<FaviconGroup> expected_favicon_groups_;
  // This is the count of favicon groups observed during the test.
  size_t favicon_count_;
};

bool DecompressDatabase(const base::FilePath& data_path) {
  base::FilePath output_file = data_path.Append(
      L"DataStore\\Data\\nouser1\\120712-0049\\DBStore\\spartan.edb");
  base::FilePath gzip_file = output_file.AddExtension(L".gz");
  std::string gzip_data;
  if (!base::ReadFileToString(gzip_file, &gzip_data))
    return false;
  if (!compression::GzipUncompress(gzip_data, &gzip_data))
    return false;
  return base::WriteFile(output_file, gzip_data.c_str(), gzip_data.size()) >= 0;
}

const char kDummyFaviconImageData[] =
    "\x42\x4D"           // Magic signature 'BM'
    "\x1E\x00\x00\x00"   // File size
    "\x00\x00\x00\x00"   // Reserved
    "\x1A\x00\x00\x00"   // Offset of the pixel data
    "\x0C\x00\x00\x00"   // Header Size
    "\x01\x00\x01\x00"   // Size: 1x1
    "\x01\x00"           // Reserved
    "\x18\x00"           // 24-bits
    "\x00\xFF\x00\x00";  // The pixel

}  // namespace

// These tests need to be browser tests in order to be able to run the OOP
// import (via ExternalProcessImporterHost) which launches a utility process.
class EdgeImporterBrowserTest : public InProcessBrowserTest {
 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    // This will launch the browser test and thus needs to happen last.
    InProcessBrowserTest::SetUp();
  }

  base::ScopedTempDir temp_dir_;

  // Overrides the default registry key for Edge tests.
  ImporterTestRegistryOverrider test_registry_overrider_;
};

IN_PROC_BROWSER_TEST_F(EdgeImporterBrowserTest, EdgeImporter) {
  // Only verified to work with ESE library on Windows 8.1 and above.
  if (base::win::GetVersion() < base::win::VERSION_WIN8_1)
    return;

  const BookmarkInfo kEdgeBookmarks[] = {
      {true,
       2,
       {"Links", "SubFolderOfLinks"},
       L"SubLink",
       "http://www.links-sublink.com/"},
      {true, 1, {"Links"}, L"TheLink", "http://www.links-thelink.com/"},
      {false, 0, {}, L"Google Home Page", "http://www.google.com/"},
      {false, 0, {}, L"TheLink", "http://www.links-thelink.com/"},
      {false, 1, {"SubFolder"}, L"Title", "http://www.link.com/"},
      {false, 0, {}, L"WithPortAndQuery", "http://host:8080/cgi?q=query"},
      {false, 1, {"a"}, L"\x4E2D\x6587", "http://chinese-title-favorite/"},
      {false, 0, {}, L"SubFolder", "http://www.subfolder.com/"},
      {false, 0, {}, L"InvalidFavicon", "http://www.invalid-favicon.com/"},
  };
  std::vector<BookmarkInfo> bookmark_entries(
      kEdgeBookmarks, kEdgeBookmarks + arraysize(kEdgeBookmarks));

  const FaviconGroup kEdgeFaviconGroup[] = {
      {L"http://www.links-sublink.com/favicon.ico",
       L"http://www.links-sublink.com"},
      {L"http://www.links-thelink.com/favicon.ico",
       L"http://www.links-thelink.com"},
      {L"http://www.google.com/favicon.ico", L"http://www.google.com"},
      {L"http://www.links-thelink.com/favicon.ico",
       L"http://www.links-thelink.com"},
      {L"http://www.link.com/favicon.ico", L"http://www.link.com"},
      {L"http://host:8080/favicon.ico", L"http://host:8080/cgi?q=query"},
      {L"http://chinese-title-favorite/favicon.ico",
       L"http://chinese-title-favorite"},
      {L"http://www.subfolder.com/favicon.ico", L"http://www.subfolder.com"},
  };

  std::vector<FaviconGroup> favicon_groups(
      kEdgeFaviconGroup, kEdgeFaviconGroup + arraysize(kEdgeFaviconGroup));

  base::FilePath data_path;
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &data_path));
  data_path = data_path.AppendASCII("edge_profile");

  base::FilePath temp_path = temp_dir_.GetPath();
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(base::CopyDirectory(data_path, temp_path, true));
    ASSERT_TRUE(DecompressDatabase(temp_path.AppendASCII("edge_profile")));
  }

  base::string16 key_path(importer::GetEdgeSettingsKey());
  base::win::RegKey key;
  ASSERT_EQ(ERROR_SUCCESS,
            key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_WRITE));
  key.WriteValue(L"FavoritesESEEnabled", 1);
  ASSERT_FALSE(importer::IsEdgeFavoritesLegacyMode());

  // Starts to import the above settings.
  // Deletes itself.
  ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
  scoped_refptr<TestObserver> observer(
      new TestObserver(bookmark_entries, favicon_groups));
  host->set_observer(observer.get());

  importer::SourceProfile source_profile;
  source_profile.importer_type = importer::TYPE_EDGE;
  source_profile.source_path = temp_path.AppendASCII("edge_profile");

  host->StartImportSettings(source_profile, browser()->profile(),
                            importer::FAVORITES, observer.get());
  base::RunLoop().Run();
}

IN_PROC_BROWSER_TEST_F(EdgeImporterBrowserTest, EdgeImporterLegacyFallback) {
  const BookmarkInfo kEdgeBookmarks[] = {
      {false, 0, {}, L"Google", "http://www.google.com/"}};
  std::vector<BookmarkInfo> bookmark_entries(
      kEdgeBookmarks, kEdgeBookmarks + arraysize(kEdgeBookmarks));
  const FaviconGroup kEdgeFaviconGroup[] = {
      {L"http://www.google.com/favicon.ico", L"http://www.google.com/"}};
  std::vector<FaviconGroup> favicon_groups(
      kEdgeFaviconGroup, kEdgeFaviconGroup + arraysize(kEdgeFaviconGroup));

  base::FilePath data_path;
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &data_path));
  data_path = data_path.AppendASCII("edge_profile");

  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(base::CopyDirectory(data_path, temp_dir_.GetPath(), true));
    ASSERT_TRUE(importer::IsEdgeFavoritesLegacyMode());
  }

  // Starts to import the above settings.
  // Deletes itself.
  ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
  scoped_refptr<TestObserver> observer(
      new TestObserver(bookmark_entries, favicon_groups));
  host->set_observer(observer.get());

  importer::SourceProfile source_profile;
  source_profile.importer_type = importer::TYPE_EDGE;
  base::FilePath source_path = temp_dir_.GetPath().AppendASCII("edge_profile");
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_NE(
        -1, base::WriteFile(
                source_path.AppendASCII("Favorites\\Google.url:favicon:$DATA"),
                kDummyFaviconImageData, sizeof(kDummyFaviconImageData)));
  }
  source_profile.source_path = source_path;

  host->StartImportSettings(source_profile, browser()->profile(),
                            importer::FAVORITES, observer.get());
  base::RunLoop().Run();
}

IN_PROC_BROWSER_TEST_F(EdgeImporterBrowserTest, EdgeImporterNoDatabase) {
  // Only verified to work with ESE library on Windows 8.1 and above.
  if (base::win::GetVersion() < base::win::VERSION_WIN8_1)
    return;

  std::vector<BookmarkInfo> bookmark_entries;
  std::vector<FaviconGroup> favicon_groups;

  base::string16 key_path(importer::GetEdgeSettingsKey());
  base::win::RegKey key;
  ASSERT_EQ(ERROR_SUCCESS,
            key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_WRITE));
  key.WriteValue(L"FavoritesESEEnabled", 1);
  ASSERT_FALSE(importer::IsEdgeFavoritesLegacyMode());

  // Starts to import the above settings.
  // Deletes itself.
  ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
  scoped_refptr<TestObserver> observer(
      new TestObserver(bookmark_entries, favicon_groups));
  host->set_observer(observer.get());

  importer::SourceProfile source_profile;
  source_profile.importer_type = importer::TYPE_EDGE;
  source_profile.source_path = temp_dir_.GetPath();

  host->StartImportSettings(source_profile, browser()->profile(),
                            importer::FAVORITES, observer.get());
  base::RunLoop().Run();
}
