// 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 "chrome/utility/importer/edge_importer_win.h"

#include <Shlobj.h>

#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/win/windows_version.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/grit/generated_resources.h"
#include "chrome/utility/importer/edge_database_reader_win.h"
#include "chrome/utility/importer/favicon_reencode.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

// Toolbar favorites are placed under this special folder name.
const base::char16 kFavoritesBarTitle[] = L"_Favorites_Bar_";
const base::char16 kSpartanDatabaseFile[] = L"spartan.edb";

struct EdgeFavoriteEntry {
  EdgeFavoriteEntry()
      : is_folder(false),
        order_number(0),
        item_id(GUID_NULL),
        parent_id(GUID_NULL) {}

  base::string16 title;
  GURL url;
  base::FilePath favicon_file;
  bool is_folder;
  int64_t order_number;
  base::Time date_updated;
  GUID item_id;
  GUID parent_id;

  std::vector<const EdgeFavoriteEntry*> children;

  ImportedBookmarkEntry ToBookmarkEntry(
      bool in_toolbar,
      const std::vector<base::string16>& path) const {
    ImportedBookmarkEntry entry;
    entry.in_toolbar = in_toolbar;
    entry.is_folder = is_folder;
    entry.url = url;
    entry.path = path;
    entry.title = title;
    entry.creation_time = date_updated;
    return entry;
  }
};

struct EdgeFavoriteEntryComparator {
  bool operator()(const EdgeFavoriteEntry* lhs,
                  const EdgeFavoriteEntry* rhs) const {
    return std::tie(lhs->order_number, lhs->title) <
           std::tie(rhs->order_number, rhs->title);
  }
};

// The name of the database file is spartan.edb, however it isn't clear how
// the intermediate path between the DataStore and the database is generated.
// Therefore we just do a simple recursive search until we find a matching name.
base::FilePath FindSpartanDatabase(const base::FilePath& profile_path) {
  base::FilePath data_path =
      profile_path.empty() ? importer::GetEdgeDataFilePath() : profile_path;
  if (data_path.empty())
    return base::FilePath();

  base::FileEnumerator enumerator(data_path.Append(L"DataStore\\Data"), true,
                                  base::FileEnumerator::FILES);
  base::FilePath path = enumerator.Next();
  while (!path.empty()) {
    if (base::EqualsCaseInsensitiveASCII(path.BaseName().value(),
                                         kSpartanDatabaseFile))
      return path;
    path = enumerator.Next();
  }
  return base::FilePath();
}

struct GuidComparator {
  bool operator()(const GUID& a, const GUID& b) const {
    return memcmp(&a, &b, sizeof(a)) < 0;
  }
};

bool ReadFaviconData(const base::FilePath& file,
                     std::vector<unsigned char>* data) {
  std::string image_data;
  if (!base::ReadFileToString(file, &image_data))
    return false;

  const unsigned char* ptr =
      reinterpret_cast<const unsigned char*>(image_data.c_str());
  return importer::ReencodeFavicon(ptr, image_data.size(), data);
}

void BuildBookmarkEntries(const EdgeFavoriteEntry& current_entry,
                          bool is_toolbar,
                          std::vector<ImportedBookmarkEntry>* bookmarks,
                          favicon_base::FaviconUsageDataList* favicons,
                          std::vector<base::string16>* path) {
  for (const EdgeFavoriteEntry* entry : current_entry.children) {
    if (entry->is_folder) {
      // If the favorites bar then load all children as toolbar items.
      if (base::EqualsCaseInsensitiveASCII(entry->title, kFavoritesBarTitle)) {
        // Replace name with Links similar to IE.
        path->push_back(L"Links");
        BuildBookmarkEntries(*entry, true, bookmarks, favicons, path);
        path->pop_back();
      } else {
        path->push_back(entry->title);
        BuildBookmarkEntries(*entry, is_toolbar, bookmarks, favicons, path);
        path->pop_back();
      }
    } else {
      bookmarks->push_back(entry->ToBookmarkEntry(is_toolbar, *path));
      favicon_base::FaviconUsageData favicon;
      if (entry->url.is_valid() && !entry->favicon_file.empty() &&
          ReadFaviconData(entry->favicon_file, &favicon.png_data)) {
        // As the database doesn't provide us a favicon URL we'll fake one.
        GURL::Replacements path_replace;
        path_replace.SetPathStr("/favicon.ico");
        favicon.favicon_url =
            entry->url.GetWithEmptyPath().ReplaceComponents(path_replace);
        favicon.urls.insert(entry->url);
        favicons->push_back(favicon);
      }
    }
  }
}

}  // namespace

EdgeImporter::EdgeImporter() {}

void EdgeImporter::StartImport(const importer::SourceProfile& source_profile,
                               uint16_t items,
                               ImporterBridge* bridge) {
  bridge_ = bridge;
  bridge_->NotifyStarted();
  source_path_ = source_profile.source_path;

  if ((items & importer::FAVORITES) && !cancelled()) {
    bridge_->NotifyItemStarted(importer::FAVORITES);
    ImportFavorites();
    bridge_->NotifyItemEnded(importer::FAVORITES);
  }
  bridge_->NotifyEnded();
}

EdgeImporter::~EdgeImporter() {}

void EdgeImporter::ImportFavorites() {
  std::vector<ImportedBookmarkEntry> bookmarks;
  favicon_base::FaviconUsageDataList favicons;
  ParseFavoritesDatabase(&bookmarks, &favicons);

  if (!bookmarks.empty() && !cancelled()) {
    const base::string16& first_folder_name =
        l10n_util::GetStringUTF16(IDS_BOOKMARK_GROUP_FROM_EDGE);
    bridge_->AddBookmarks(bookmarks, first_folder_name);
  }
  if (!favicons.empty() && !cancelled())
    bridge_->SetFavicons(favicons);
}

// From Edge 13 (released with Windows 10 TH2), Favorites are stored in a JET
// database within the Edge local storage. The import uses the ESE library to
// open and read the data file. The data is stored in a Favorites table with
// the following schema.
// Column Name          Column Type
// ------------------------------------------
// DateUpdated          LongLong - FILETIME
// FaviconFile          LongText - Relative path
// HashedUrl            ULong
// IsDeleted            Bit
// IsFolder             Bit
// ItemId               Guid
// OrderNumber          LongLong
// ParentId             Guid
// RoamDisabled         Bit
// RowId                Long
// Title                LongText
// URL                  LongText
void EdgeImporter::ParseFavoritesDatabase(
    std::vector<ImportedBookmarkEntry>* bookmarks,
    favicon_base::FaviconUsageDataList* favicons) {
  base::FilePath database_path = FindSpartanDatabase(source_path_);
  if (database_path.empty())
    return;

  base::FilePath log_folder = database_path.DirName().Append(L"LogFiles");

  EdgeDatabaseReader database;

  // If the log file directory does not exist, don't set the log_folder
  // attribute, as the open database operation will fail in such cases.
  // The log folder will usually not be present when running the unit tests.
  if (base::PathExists(log_folder))
    database.set_log_folder(log_folder.value());
  if (!database.OpenDatabase(database_path.value())) {
    DVLOG(1) << "Error opening database " << database.GetErrorMessage();
    return;
  }

  std::unique_ptr<EdgeDatabaseTableEnumerator> enumerator =
      database.OpenTableEnumerator(L"Favorites");
  if (!enumerator) {
    DVLOG(1) << "Error opening database table " << database.GetErrorMessage();
    return;
  }

  if (!enumerator->Reset())
    return;

  std::map<GUID, EdgeFavoriteEntry, GuidComparator> database_entries;
  base::FilePath favicon_base =
      source_path_.empty() ? importer::GetEdgeDataFilePath() : source_path_;
  favicon_base = favicon_base.Append(L"DataStore");

  do {
    EdgeFavoriteEntry entry;
    bool is_deleted = false;
    if (!enumerator->RetrieveColumn(L"IsDeleted", &is_deleted))
      continue;
    if (is_deleted)
      continue;
    if (!enumerator->RetrieveColumn(L"IsFolder", &entry.is_folder))
      continue;
    base::string16 url;
    if (!enumerator->RetrieveColumn(L"URL", &url))
      continue;
    entry.url = GURL(url);
    if (!entry.is_folder && !entry.url.is_valid())
      continue;
    if (!enumerator->RetrieveColumn(L"Title", &entry.title))
      continue;
    base::string16 favicon_file;
    if (!enumerator->RetrieveColumn(L"FaviconFile", &favicon_file))
      continue;
    if (!favicon_file.empty())
      entry.favicon_file = favicon_base.Append(favicon_file);
    if (!enumerator->RetrieveColumn(L"ParentId", &entry.parent_id))
      continue;
    if (!enumerator->RetrieveColumn(L"ItemId", &entry.item_id))
      continue;
    if (!enumerator->RetrieveColumn(L"OrderNumber", &entry.order_number))
      continue;
    FILETIME data_updated;
    if (!enumerator->RetrieveColumn(L"DateUpdated", &data_updated))
      continue;
    entry.date_updated = base::Time::FromFileTime(data_updated);
    database_entries[entry.item_id] = entry;
  } while (enumerator->Next() && !cancelled());

  // Build simple tree.
  EdgeFavoriteEntry root_entry;
  for (auto& entry : database_entries) {
    auto found_parent = database_entries.find(entry.second.parent_id);
    if (found_parent == database_entries.end() ||
        !found_parent->second.is_folder) {
      root_entry.children.push_back(&entry.second);
    } else {
      found_parent->second.children.push_back(&entry.second);
    }
  }
  // With tree built sort the children of each node including the root.
  std::sort(root_entry.children.begin(), root_entry.children.end(),
            EdgeFavoriteEntryComparator());
  for (auto& entry : database_entries) {
    std::sort(entry.second.children.begin(), entry.second.children.end(),
              EdgeFavoriteEntryComparator());
  }
  std::vector<base::string16> path;
  BuildBookmarkEntries(root_entry, false, bookmarks, favicons, &path);
}
