// 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/sync_sessions/open_tabs_ui_delegate_impl.h"

#include <algorithm>

#include "components/sync_sessions/favicon_cache.h"
#include "components/sync_sessions/sync_sessions_client.h"
#include "components/sync_sessions/synced_session_tracker.h"

namespace sync_sessions {
namespace {

// Comparator function for use with std::sort that will sort tabs by
// descending timestamp (i.e., most recent first).
bool TabsRecencyComparator(const sessions::SessionTab* t1,
                           const sessions::SessionTab* t2) {
  return t1->timestamp > t2->timestamp;
}

// Comparator function for use with std::sort that will sort sessions by
// descending modified_time (i.e., most recent first).
bool SessionsRecencyComparator(const SyncedSession* s1,
                               const SyncedSession* s2) {
  return s1->modified_time > s2->modified_time;
}

}  // namespace

OpenTabsUIDelegateImpl::OpenTabsUIDelegateImpl(
    const SyncSessionsClient* sessions_client,
    const SyncedSessionTracker* session_tracker,
    const FaviconCache* favicon_cache,
    const DeleteForeignSessionCallback& delete_foreign_session_cb)
    : sessions_client_(sessions_client),
      session_tracker_(session_tracker),
      favicon_cache_(favicon_cache),
      delete_foreign_session_cb_(delete_foreign_session_cb) {}

OpenTabsUIDelegateImpl::~OpenTabsUIDelegateImpl() {}

bool OpenTabsUIDelegateImpl::GetSyncedFaviconForPageURL(
    const std::string& page_url,
    scoped_refptr<base::RefCountedMemory>* favicon_png) const {
  return favicon_cache_->GetSyncedFaviconForPageURL(GURL(page_url),
                                                    favicon_png);
}

bool OpenTabsUIDelegateImpl::GetAllForeignSessions(
    std::vector<const SyncedSession*>* sessions) {
  if (!session_tracker_->LookupAllForeignSessions(
          sessions, SyncedSessionTracker::PRESENTABLE))
    return false;
  std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator);
  return true;
}

bool OpenTabsUIDelegateImpl::GetForeignSession(
    const std::string& tag,
    std::vector<const sessions::SessionWindow*>* windows) {
  return session_tracker_->LookupSessionWindows(tag, windows);
}

bool OpenTabsUIDelegateImpl::GetForeignTab(const std::string& tag,
                                           const SessionID::id_type tab_id,
                                           const sessions::SessionTab** tab) {
  const sessions::SessionTab* synced_tab = nullptr;
  bool success = session_tracker_->LookupSessionTab(tag, tab_id, &synced_tab);
  if (success)
    *tab = synced_tab;
  return success;
}

bool OpenTabsUIDelegateImpl::GetForeignSessionTabs(
    const std::string& tag,
    std::vector<const sessions::SessionTab*>* tabs) {
  std::vector<const sessions::SessionWindow*> windows;
  if (!session_tracker_->LookupSessionWindows(tag, &windows))
    return false;

  // Prune those tabs that are not syncable or are NewTabPage, then sort them
  // from most recent to least recent, independent of which window the tabs were
  // from.
  for (size_t j = 0; j < windows.size(); ++j) {
    const sessions::SessionWindow* window = windows[j];
    for (size_t t = 0; t < window->tabs.size(); ++t) {
      sessions::SessionTab* const tab = window->tabs[t].get();
      if (tab->navigations.empty())
        continue;
      const sessions::SerializedNavigationEntry& current_navigation =
          tab->navigations.at(tab->normalized_navigation_index());
      if (!sessions_client_->ShouldSyncURL(current_navigation.virtual_url()))
        continue;
      tabs->push_back(tab);
    }
  }
  std::sort(tabs->begin(), tabs->end(), TabsRecencyComparator);
  return true;
}

void OpenTabsUIDelegateImpl::DeleteForeignSession(const std::string& tag) {
  delete_foreign_session_cb_.Run(tag);
}

bool OpenTabsUIDelegateImpl::GetLocalSession(
    const SyncedSession** local_session) {
  return session_tracker_->LookupLocalSession(local_session);
}

}  // namespace sync_sessions
