// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/tab_ui_helper.h"

#include "base/functional/bind.h"
#include "build/build_config.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/favicon/favicon_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/grit/generated_resources.h"
#include "components/favicon/core/favicon_service.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/url_formatter/url_formatter.h"
#include "content/public/browser/invalidate_type.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/resources/grit/ui_resources.h"

namespace {

std::u16string FormatUrlToSubdomain(const GURL& url) {
  std::u16string formated_url = url_formatter::FormatUrl(
      url, url_formatter::kFormatUrlOmitTrivialSubdomains,
      base::UnescapeRule::SPACES, nullptr, nullptr, nullptr);
  return base::UTF8ToUTF16(GURL(formated_url).host());
}

}  // namespace

TabUIHelper::TabUIData::TabUIData(const GURL& url)
    : title(FormatUrlToSubdomain(url)),
      favicon(favicon::GetDefaultFaviconModel()) {}

TabUIHelper::TabUIHelper(content::WebContents* contents)
    : WebContentsObserver(contents),
      content::WebContentsUserData<TabUIHelper>(*contents) {}

TabUIHelper::~TabUIHelper() = default;

std::u16string TabUIHelper::GetTitle() const {
  const std::u16string& contents_title = web_contents()->GetTitle();
  if (!contents_title.empty())
    return contents_title;

  if (tab_ui_data_)
    return tab_ui_data_->title;

#if BUILDFLAG(IS_MAC)
  return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
#else
  return std::u16string();
#endif
}

ui::ImageModel TabUIHelper::GetFavicon() const {
  return ShouldUseFaviconFromHistory() && tab_ui_data_
             ? tab_ui_data_->favicon
             : ui::ImageModel::FromImage(
                   favicon::TabFaviconFromWebContents(web_contents()));
}

bool TabUIHelper::ShouldHideThrobber() const {
  // Hiding throbber and using favicon from history is desired when a new
  // background tab's initial navigation is delayed, so the user has a way to
  // see what the tab is.
  if (ShouldUseFaviconFromHistory())
    return true;

  // We also want to hide a background tab's throbber during page load if it is
  // created by session restore. A restored tab's favicon is already fetched
  // by |SessionRestoreDelegate|.
  if (created_by_session_restore_ && !was_active_at_least_once_)
    return true;

  return false;
}

void TabUIHelper::NotifyInitialNavigationDelayed(bool is_navigation_delayed) {
  DCHECK(web_contents()->GetController().IsInitialNavigation());

  is_navigation_delayed_ = is_navigation_delayed;
  if (!is_navigation_delayed_)
    return;

  tab_ui_data_ = std::make_unique<TabUIData>(web_contents()->GetVisibleURL());
  web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);

  // When fetching favicon from history, we first try the exact URL, and then
  // fall back to the host.
  FetchFaviconFromHistory(web_contents()->GetVisibleURL(),
                          base::BindOnce(&TabUIHelper::OnURLFaviconFetched,
                                         weak_ptr_factory_.GetWeakPtr()));
}

void TabUIHelper::DidStopLoading() {
  // Reset the properties after the initial navigation finishes loading, so that
  // latter navigations are not affected. Note that the prerendered page won't
  // reset the properties because DidStopLoading is not called for prerendering.
  is_navigation_delayed_ = false;
  created_by_session_restore_ = false;
  tab_ui_data_.reset();
}

bool TabUIHelper::ShouldUseFaviconFromHistory() const {
  return web_contents()->GetController().IsInitialNavigation() &&
         is_navigation_delayed_ && !was_active_at_least_once_;
}

void TabUIHelper::FetchFaviconFromHistory(
    const GURL& url,
    favicon_base::FaviconImageCallback callback) {
  Profile* profile =
      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
  favicon::FaviconService* favicon_service =
      FaviconServiceFactory::GetForProfile(profile,
                                           ServiceAccessType::EXPLICIT_ACCESS);
  // |favicon_service| might be null when testing.
  if (favicon_service) {
    favicon_service->GetFaviconImageForPageURL(url, std::move(callback),
                                               &favicon_tracker_);
  }
}

void TabUIHelper::OnURLFaviconFetched(
    const favicon_base::FaviconImageResult& favicon) {
  if (!ShouldUseFaviconFromHistory())
    return;

  if (!favicon.image.IsEmpty()) {
    UpdateFavicon(favicon);
    return;
  }

  FetchFaviconFromHistory(web_contents()->GetVisibleURL().GetWithEmptyPath(),
                          base::BindOnce(&TabUIHelper::OnHostFaviconFetched,
                                         weak_ptr_factory_.GetWeakPtr()));
}

void TabUIHelper::OnHostFaviconFetched(
    const favicon_base::FaviconImageResult& favicon) {
  if (!ShouldUseFaviconFromHistory())
    return;

  if (!favicon.image.IsEmpty())
    UpdateFavicon(favicon);
}

void TabUIHelper::UpdateFavicon(
    const favicon_base::FaviconImageResult& favicon) {
  if (tab_ui_data_) {
    // TODO(crbug.com/1099602): This should be updated to support ui::ImageModel
    // instead of gfx::Image.
    tab_ui_data_->favicon = ui::ImageModel::FromImage(favicon.image);
    web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
  }
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(TabUIHelper);
