// 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;

  EdgeDatabaseReader database;
  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);
}
