// Copyright 2018 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 "components/ntp_tiles/custom_links_manager_impl.h"

#include <memory>
#include <string>
#include <utility>

#include "base/auto_reset.h"
#include "base/bind.h"
#include "components/ntp_tiles/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"

namespace ntp_tiles {

namespace {

const int kMaxNumLinks = 10;

}  // namespace

CustomLinksManagerImpl::CustomLinksManagerImpl(
    PrefService* prefs,
    history::HistoryService* history_service)
    : prefs_(prefs),
      store_(prefs),
      history_service_observer_(this),
      weak_ptr_factory_(this) {
  DCHECK(prefs);
  if (history_service)
    history_service_observer_.Add(history_service);
  if (IsInitialized())
    current_links_ = store_.RetrieveLinks();

  base::RepeatingClosure callback =
      base::BindRepeating(&CustomLinksManagerImpl::OnPreferenceChanged,
                          weak_ptr_factory_.GetWeakPtr());
  pref_change_registrar_.Init(prefs_);
  pref_change_registrar_.Add(prefs::kCustomLinksInitialized, callback);
  pref_change_registrar_.Add(prefs::kCustomLinksList, callback);
}

CustomLinksManagerImpl::~CustomLinksManagerImpl() = default;

bool CustomLinksManagerImpl::Initialize(const NTPTilesVector& tiles) {
  if (IsInitialized())
    return false;

  for (const NTPTile& tile : tiles)
    current_links_.emplace_back(Link{tile.url, tile.title, true});

  {
    base::AutoReset<bool> auto_reset(&updating_preferences_, true);
    prefs_->SetBoolean(prefs::kCustomLinksInitialized, true);
  }
  StoreLinks();
  return true;
}

void CustomLinksManagerImpl::Uninitialize() {
  {
    base::AutoReset<bool> auto_reset(&updating_preferences_, true);
    prefs_->SetBoolean(prefs::kCustomLinksInitialized, false);
  }
  ClearLinks();
}

bool CustomLinksManagerImpl::IsInitialized() const {
  return prefs_->GetBoolean(prefs::kCustomLinksInitialized);
}

const std::vector<CustomLinksManager::Link>& CustomLinksManagerImpl::GetLinks()
    const {
  return current_links_;
}

bool CustomLinksManagerImpl::AddLink(const GURL& url,
                                     const base::string16& title) {
  if (!IsInitialized() || !url.is_valid() ||
      current_links_.size() == kMaxNumLinks) {
    return false;
  }

  if (FindLinkWithUrl(url) != current_links_.end())
    return false;

  previous_links_ = current_links_;
  current_links_.emplace_back(Link{url, title, false});
  StoreLinks();
  return true;
}

bool CustomLinksManagerImpl::UpdateLink(const GURL& url,
                                        const GURL& new_url,
                                        const base::string16& new_title) {
  if (!IsInitialized() || !url.is_valid() ||
      (new_url.is_empty() && new_title.empty())) {
    return false;
  }

  // Do not update if |new_url| is invalid or already exists in the list.
  if (!new_url.is_empty() &&
      (!new_url.is_valid() ||
       FindLinkWithUrl(new_url) != current_links_.end())) {
    return false;
  }

  auto it = FindLinkWithUrl(url);
  if (it == current_links_.end())
    return false;

  // At this point, we will be modifying at least one of the values.
  previous_links_ = current_links_;

  if (!new_url.is_empty())
    it->url = new_url;
  if (!new_title.empty())
    it->title = new_title;
  it->is_most_visited = false;

  StoreLinks();
  return true;
}

bool CustomLinksManagerImpl::ReorderLink(const GURL& url, size_t new_pos) {
  if (!IsInitialized() || !url.is_valid() || new_pos < 0 ||
      new_pos >= current_links_.size()) {
    return false;
  }

  auto curr_it = FindLinkWithUrl(url);
  if (curr_it == current_links_.end())
    return false;

  auto new_it = current_links_.begin() + new_pos;
  if (new_it == curr_it)
    return false;

  previous_links_ = current_links_;

  // If the new position is to the left of the current position, left rotate the
  // range [new_pos, curr_pos] until the link is first.
  if (new_it < curr_it)
    std::rotate(new_it, curr_it, curr_it + 1);
  // If the new position is to the right, we only need to left rotate the range
  // [curr_pos, new_pos] once so that the link is last.
  else
    std::rotate(curr_it, curr_it + 1, new_it + 1);

  StoreLinks();
  return true;
}

bool CustomLinksManagerImpl::DeleteLink(const GURL& url) {
  if (!IsInitialized() || !url.is_valid())
    return false;

  auto it = FindLinkWithUrl(url);
  if (it == current_links_.end())
    return false;

  previous_links_ = current_links_;
  current_links_.erase(it);
  StoreLinks();
  return true;
}

bool CustomLinksManagerImpl::UndoAction() {
  if (!IsInitialized() || !previous_links_.has_value())
    return false;

  // Replace the current links with the previous state.
  current_links_ = *previous_links_;
  previous_links_ = base::nullopt;
  StoreLinks();
  return true;
}

void CustomLinksManagerImpl::ClearLinks() {
  {
    base::AutoReset<bool> auto_reset(&updating_preferences_, true);
    store_.ClearLinks();
  }
  current_links_.clear();
  previous_links_ = base::nullopt;
}

void CustomLinksManagerImpl::StoreLinks() {
  base::AutoReset<bool> auto_reset(&updating_preferences_, true);
  store_.StoreLinks(current_links_);
}

std::vector<CustomLinksManager::Link>::iterator
CustomLinksManagerImpl::FindLinkWithUrl(const GURL& url) {
  return std::find_if(current_links_.begin(), current_links_.end(),
                      [&url](const Link& link) { return link.url == url; });
}

std::unique_ptr<base::CallbackList<void()>::Subscription>
CustomLinksManagerImpl::RegisterCallbackForOnChanged(
    base::RepeatingClosure callback) {
  return callback_list_.Add(callback);
}

// history::HistoryServiceObserver implementation.
void CustomLinksManagerImpl::OnURLsDeleted(
    history::HistoryService* history_service,
    const history::DeletionInfo& deletion_info) {
  // We don't care about expired entries.
  if (!IsInitialized() || deletion_info.is_from_expiration())
    return;

  size_t initial_size = current_links_.size();
  if (deletion_info.IsAllHistory()) {
    base::EraseIf(current_links_,
                  [](auto& link) { return link.is_most_visited; });
  } else {
    for (const history::URLRow& row : deletion_info.deleted_rows()) {
      auto it = FindLinkWithUrl(row.url());
      if (it != current_links_.end() && it->is_most_visited)
        current_links_.erase(it);
    }
  }
  StoreLinks();
  previous_links_ = base::nullopt;

  // Alert MostVisitedSites that some links have been deleted.
  if (initial_size != current_links_.size())
    callback_list_.Notify();
}

void CustomLinksManagerImpl::HistoryServiceBeingDeleted(
    history::HistoryService* history_service) {
  history_service_observer_.RemoveAll();
}

void CustomLinksManagerImpl::OnPreferenceChanged() {
  if (updating_preferences_)
    return;

  if (IsInitialized())
    current_links_ = store_.RetrieveLinks();
  else
    current_links_.clear();
  previous_links_ = base::nullopt;
  callback_list_.Notify();
}

// static
void CustomLinksManagerImpl::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* user_prefs) {
  user_prefs->RegisterBooleanPref(
      prefs::kCustomLinksInitialized, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  CustomLinksStore::RegisterProfilePrefs(user_prefs);
}

}  // namespace ntp_tiles
