// Copyright 2016 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/safe_browsing/base_ui_manager.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/i18n/rtl.h"
#include "base/memory/ptr_util.h"
#include "base/supports_user_data.h"
#include "components/safe_browsing/base_blocking_page.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"

using content::BrowserThread;
using content::NavigationEntry;
using content::WebContents;
using safe_browsing::HitReport;
using safe_browsing::SBThreatType;

namespace {

const void* const kWhitelistKey = &kWhitelistKey;

// A WhitelistUrlSet holds the set of URLs that have been whitelisted
// for a specific WebContents, along with pending entries that are still
// undecided. Each URL is associated with the first SBThreatType that
// was seen for that URL. The URLs in this set should come from
// GetWhitelistUrl() or GetMainFrameWhitelistUrlForResource() (in
// SafeBrowsingUIManager)
class WhitelistUrlSet : public base::SupportsUserData::Data {
 public:
  WhitelistUrlSet() {}
  bool Contains(const GURL url, SBThreatType* threat_type) {
    auto found = map_.find(url);
    if (found == map_.end())
      return false;
    if (threat_type)
      *threat_type = found->second;
    return true;
  }
  void RemovePending(const GURL& url) {
    DCHECK(pending_.end() != pending_.find(url));
    if (--pending_[url].second < 1)
      pending_.erase(url);
  }
  void Remove(const GURL& url) { map_.erase(url); }
  void Insert(const GURL url, SBThreatType threat_type) {
    if (Contains(url, nullptr))
      return;
    map_[url] = threat_type;
    RemoveAllPending(url);
  }
  bool ContainsPending(const GURL& url, SBThreatType* threat_type) {
    auto found = pending_.find(url);
    if (found == pending_.end())
      return false;
    if (threat_type)
      *threat_type = found->second.first;
    return true;
  }
  void InsertPending(const GURL url, SBThreatType threat_type) {
    if (pending_.find(url) != pending_.end()) {
      pending_[url].first = threat_type;
      pending_[url].second++;
      return;
    }
    pending_[url] = {threat_type, 1};
  }

 protected:
  // Method to remove all the instances of a website in the pending list
  // disregarding the count. Used when adding a site to the permanent list.
  void RemoveAllPending(const GURL& url) { pending_.erase(url); }

 private:
  std::map<GURL, SBThreatType> map_;
  // Keep a count of how many times a site has been added to the pending list
  // in order to solve a problem where upon reloading an interstitial, a site
  // would be re-added to and removed from the whitelist in the wrong order.
  std::map<GURL, std::pair<SBThreatType, int>> pending_;
  DISALLOW_COPY_AND_ASSIGN(WhitelistUrlSet);
};

// Returns the URL that should be used in a WhitelistUrlSet for the
// resource loaded from |url| on a navigation |entry|.
GURL GetWhitelistUrl(const GURL& url,
                     bool is_subresource,
                     NavigationEntry* entry) {
  if (is_subresource) {
    if (!entry)
      return GURL();
    return entry->GetURL().GetWithEmptyPath();
  }
  return url.GetWithEmptyPath();
}

WhitelistUrlSet* GetOrCreateWhitelist(WebContents* web_contents) {
  WhitelistUrlSet* site_list =
      static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey));
  if (!site_list) {
    site_list = new WhitelistUrlSet;
    web_contents->SetUserData(kWhitelistKey, base::WrapUnique(site_list));
  }
  return site_list;
}

}  // namespace

namespace safe_browsing {

BaseUIManager::BaseUIManager() {}

BaseUIManager::~BaseUIManager() {}

bool BaseUIManager::IsWhitelisted(const UnsafeResource& resource) {
  NavigationEntry* entry = nullptr;
  if (resource.is_subresource) {
    entry = resource.GetNavigationEntryForResource();
  }
  SBThreatType unused_threat_type;
  return IsUrlWhitelistedOrPendingForWebContents(
      resource.url, resource.is_subresource, entry,
      resource.web_contents_getter.Run(), true, &unused_threat_type);
}

// Check if the user has already seen and/or ignored a SB warning for this
// WebContents and top-level domain.
bool BaseUIManager::IsUrlWhitelistedOrPendingForWebContents(
    const GURL& url,
    bool is_subresource,
    NavigationEntry* entry,
    WebContents* web_contents,
    bool whitelist_only,
    SBThreatType* threat_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  GURL lookup_url = GetWhitelistUrl(url, is_subresource, entry);
  if (lookup_url.is_empty())
    return false;

  WhitelistUrlSet* site_list =
      static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey));
  if (!site_list)
    return false;

  bool whitelisted = site_list->Contains(lookup_url, threat_type);
  if (whitelist_only) {
    return whitelisted;
  } else {
    return whitelisted || site_list->ContainsPending(lookup_url, threat_type);
  }
}

void BaseUIManager::OnBlockingPageDone(
    const std::vector<UnsafeResource>& resources,
    bool proceed,
    WebContents* web_contents,
    const GURL& main_frame_url) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  for (const auto& resource : resources) {
    if (!resource.callback.is_null()) {
      DCHECK(resource.callback_thread);
      resource.callback_thread->PostTask(
          FROM_HERE, base::Bind(resource.callback, proceed));
    }

    GURL whitelist_url = GetWhitelistUrl(
        main_frame_url, false /* is subresource */,
        nullptr /* no navigation entry needed for main resource */);
    if (proceed) {
      AddToWhitelistUrlSet(whitelist_url, web_contents,
                           false /* Pending -> permanent */,
                           resource.threat_type);
    } else if (web_contents) {
      // |web_contents| doesn't exist if the tab has been closed.
      RemoveWhitelistUrlSet(whitelist_url, web_contents,
                            true /* from_pending_only */);
    }
  }
}

void BaseUIManager::DisplayBlockingPage(
    const UnsafeResource& resource) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (resource.is_subresource && !resource.is_subframe) {
    // Sites tagged as serving Unwanted Software should only show a warning for
    // main-frame or sub-frame resource. Similar warning restrictions should be
    // applied to malware sites tagged as "landing sites" (see "Types of
    // Malware sites" under
    // https://developers.google.com/safe-browsing/developers_guide_v3#UserWarnings).
    if (resource.threat_type == SB_THREAT_TYPE_URL_UNWANTED ||
        (resource.threat_type == SB_THREAT_TYPE_URL_MALWARE &&
         resource.threat_metadata.threat_pattern_type ==
             ThreatPatternType::MALWARE_LANDING)) {
      if (!resource.callback.is_null()) {
        DCHECK(resource.callback_thread);
        resource.callback_thread->PostTask(FROM_HERE,
                                           base::Bind(resource.callback, true));
      }

      return;
    }
  }

  // The tab might have been closed. If it was closed, just act as if "Don't
  // Proceed" had been chosen.
  WebContents* web_contents = resource.web_contents_getter.Run();
  if (!web_contents) {
    OnBlockingPageDone(std::vector<UnsafeResource>{resource},
                       false /* proceed */,
                       web_contents,
                       GetMainFrameWhitelistUrlForResource(resource));
    return;
  }

  // Check if the user has already ignored a SB warning for the same WebContents
  // and top-level domain.
  if (IsWhitelisted(resource)) {
    if (!resource.callback.is_null()) {
      DCHECK(resource.callback_thread);
      resource.callback_thread->PostTask(FROM_HERE,
                                         base::Bind(resource.callback, true));
    }
    return;
  }

  if (resource.threat_type != SB_THREAT_TYPE_SAFE) {
    CreateAndSendHitReport(resource);
  }

  AddToWhitelistUrlSet(GetMainFrameWhitelistUrlForResource(resource),
                       resource.web_contents_getter.Run(),
                       true /* A decision is now pending */,
                       resource.threat_type);
  ShowBlockingPageForResource(resource);
}

void BaseUIManager::EnsureWhitelistCreated(
    WebContents* web_contents) {
  GetOrCreateWhitelist(web_contents);
}

void BaseUIManager::CreateAndSendHitReport(const UnsafeResource& resource) {}

void BaseUIManager::ShowBlockingPageForResource(
    const UnsafeResource& resource) {
  BaseBlockingPage::ShowBlockingPage(this, resource);
}

// A SafeBrowsing hit is sent after a blocking page for malware/phishing
// or after the warning dialog for download urls, only for extended_reporting
// users who are not in incognito mode.
void BaseUIManager::MaybeReportSafeBrowsingHit(
    const HitReport& hit_report,
    const content::WebContents* web_contents) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return;
}

// If the user had opted-in to send ThreatDetails, this gets called
// when the report is ready.
void BaseUIManager::SendSerializedThreatDetails(
    const std::string& serialized) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return;
}

// Record this domain in the given WebContents as either whitelisted or
// pending whitelisting (if an interstitial is currently displayed). If an
// existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet.
void BaseUIManager::AddToWhitelistUrlSet(const GURL& whitelist_url,
                                         WebContents* web_contents,
                                         bool pending,
                                         SBThreatType threat_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // A WebContents might not exist if the tab has been closed.
  if (!web_contents)
    return;

  WhitelistUrlSet* site_list = GetOrCreateWhitelist(web_contents);

  if (whitelist_url.is_empty())
    return;

  if (pending) {
    site_list->InsertPending(whitelist_url, threat_type);
  } else {
    site_list->Insert(whitelist_url, threat_type);
  }

  // Notify security UI that security state has changed.
  web_contents->DidChangeVisibleSecurityState();
}

const std::string BaseUIManager::app_locale() const {
  return base::i18n::GetConfiguredLocale();
}

history::HistoryService* BaseUIManager::history_service(
    content::WebContents* web_contents) {
  // TODO(jialiul): figure out how to get HistoryService from webview.
  return nullptr;
}

const GURL BaseUIManager::default_safe_page() const {
  return GURL(url::kAboutBlankURL);
}

void BaseUIManager::RemoveWhitelistUrlSet(const GURL& whitelist_url,
                                          WebContents* web_contents,
                                          bool from_pending_only) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // A WebContents might not exist if the tab has been closed.
  if (!web_contents)
    return;

  // Use |web_contents| rather than |resource.web_contents_getter|
  // here. By this point, a "Back" navigation could have already been
  // committed, so the page loading |resource| might be gone and
  // |web_contents_getter| may no longer be valid.
  WhitelistUrlSet* site_list =
      static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey));

  if (whitelist_url.is_empty())
    return;

  // Note that this function does not DCHECK that |whitelist_url|
  // appears in the pending whitelist. In the common case, it's expected
  // that a URL is in the pending whitelist when it is removed, but it's
  // not always the case. For example, if there are several blocking
  // pages queued up for different resources on the same page, and the
  // user goes back to dimiss the first one, the subsequent blocking
  // pages get dismissed as well (as if the user had clicked "Back to
  // safety" on each of them). In this case, the first dismissal will
  // remove the main-frame URL from the pending whitelist, so the
  // main-frame URL will have already been removed when the subsequent
  // blocking pages are dismissed.
  if (site_list && site_list->ContainsPending(whitelist_url, nullptr))
    site_list->RemovePending(whitelist_url);

  if (!from_pending_only && site_list &&
      site_list->Contains(whitelist_url, nullptr)) {
    site_list->Remove(whitelist_url);
  }

  // Notify security UI that security state has changed.
  web_contents->DidChangeVisibleSecurityState();
}

// static
GURL BaseUIManager::GetMainFrameWhitelistUrlForResource(
    const security_interstitials::UnsafeResource& resource) {
  if (resource.is_subresource) {
    NavigationEntry* entry = resource.GetNavigationEntryForResource();
    if (!entry)
      return GURL();
    return entry->GetURL().GetWithEmptyPath();
  }
  return resource.url.GetWithEmptyPath();
}

}  // namespace safe_browsing
