// Copyright (c) 2012 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/browser/extensions/user_script_listener.h"

#include "base/bind.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/resource_throttle.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/url_pattern.h"
#include "net/url_request/url_request.h"

using content::BrowserThread;
using content::ResourceThrottle;
using content::ResourceType;

namespace extensions {

class UserScriptListener::Throttle
    : public ResourceThrottle,
      public base::SupportsWeakPtr<UserScriptListener::Throttle> {
 public:
  Throttle() : should_defer_(true), did_defer_(false) {
  }

  void ResumeIfDeferred() {
    DCHECK(should_defer_);
    should_defer_ = false;
    // Only resume the request if |this| has deferred it.
    if (did_defer_) {
      UMA_HISTOGRAM_TIMES("Extensions.ThrottledNetworkRequestDelay",
                          timer_->Elapsed());
      Resume();
    }
  }

  // ResourceThrottle implementation:
  void WillStartRequest(bool* defer) override {
    // Only defer requests if Resume has not yet been called.
    if (should_defer_) {
      *defer = true;
      did_defer_ = true;
      timer_.reset(new base::ElapsedTimer());
    }
  }

  const char* GetNameForLogging() const override {
    return "UserScriptListener::Throttle";
  }

 private:
  bool should_defer_;
  bool did_defer_;
  std::unique_ptr<base::ElapsedTimer> timer_;

  DISALLOW_COPY_AND_ASSIGN(Throttle);
};

struct UserScriptListener::ProfileData {
  // True if the user scripts contained in |url_patterns| are ready for
  // injection.
  bool user_scripts_ready;

  // A list of URL patterns that have will have user scripts applied to them.
  URLPatterns url_patterns;

  ProfileData() : user_scripts_ready(false) {}
};

UserScriptListener::UserScriptListener()
    : user_scripts_ready_(false), extension_registry_observer_(this) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  for (auto* profile :
       g_browser_process->profile_manager()->GetLoadedProfiles()) {
    extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
  }

  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
                 content::NotificationService::AllSources());

  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
                 content::NotificationService::AllSources());
  registrar_.Add(this,
                 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
                 content::NotificationService::AllSources());
}

ResourceThrottle* UserScriptListener::CreateResourceThrottle(
    const GURL& url,
    ResourceType resource_type) {
  if (!ShouldDelayRequest(url, resource_type))
    return NULL;

  Throttle* throttle = new Throttle();
  throttles_.push_back(throttle->AsWeakPtr());
  return throttle;
}

UserScriptListener::~UserScriptListener() {
}

bool UserScriptListener::ShouldDelayRequest(const GURL& url,
                                            ResourceType resource_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // If it's a frame load, then we need to check the URL against the list of
  // user scripts to see if we need to wait.
  if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME &&
      resource_type != content::RESOURCE_TYPE_SUB_FRAME)
    return false;

  // Note: we could delay only requests made by the profile who is causing the
  // delay, but it's a little more complicated to associate requests with the
  // right profile. Since this is a rare case, we'll just take the easy way
  // out.
  if (user_scripts_ready_)
    return false;

  for (ProfileDataMap::const_iterator pt = profile_data_.begin();
       pt != profile_data_.end(); ++pt) {
    for (URLPatterns::const_iterator it = pt->second.url_patterns.begin();
         it != pt->second.url_patterns.end(); ++it) {
      if ((*it).MatchesURL(url)) {
        // One of the user scripts wants to inject into this request, but the
        // script isn't ready yet. Delay the request.
        return true;
      }
    }
  }

  return false;
}

void UserScriptListener::StartDelayedRequests() {
  UMA_HISTOGRAM_COUNTS_100("Extensions.ThrottledNetworkRequests",
                           throttles_.size());
  WeakThrottleList::const_iterator it;
  for (it = throttles_.begin(); it != throttles_.end(); ++it) {
    if (it->get())
      (*it)->ResumeIfDeferred();
  }
  throttles_.clear();
}

void UserScriptListener::CheckIfAllUserScriptsReady() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  bool was_ready = user_scripts_ready_;

  user_scripts_ready_ = true;
  for (ProfileDataMap::const_iterator it = profile_data_.begin();
       it != profile_data_.end(); ++it) {
    if (!it->second.user_scripts_ready)
      user_scripts_ready_ = false;
  }

  if (user_scripts_ready_ && !was_ready)
    StartDelayedRequests();
}

void UserScriptListener::UserScriptsReady(void* profile_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  profile_data_[profile_id].user_scripts_ready = true;
  CheckIfAllUserScriptsReady();
}

void UserScriptListener::ProfileDestroyed(void* profile_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  profile_data_.erase(profile_id);

  // We may have deleted the only profile we were waiting on.
  CheckIfAllUserScriptsReady();
}

void UserScriptListener::AppendNewURLPatterns(void* profile_id,
                                              const URLPatterns& new_patterns) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  user_scripts_ready_ = false;

  ProfileData& data = profile_data_[profile_id];
  data.user_scripts_ready = false;

  data.url_patterns.insert(data.url_patterns.end(),
                           new_patterns.begin(), new_patterns.end());
}

void UserScriptListener::ReplaceURLPatterns(void* profile_id,
                                            const URLPatterns& patterns) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  ProfileData& data = profile_data_[profile_id];
  data.url_patterns = patterns;
}

void UserScriptListener::CollectURLPatterns(const Extension* extension,
                                            URLPatterns* patterns) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  for (const std::unique_ptr<UserScript>& script :
       ContentScriptsInfo::GetContentScripts(extension)) {
    patterns->insert(patterns->end(), script->url_patterns().begin(),
                     script->url_patterns().end());
  }
}

void UserScriptListener::Observe(int type,
                                 const content::NotificationSource& source,
                                 const content::NotificationDetails& details) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  switch (type) {
    case chrome::NOTIFICATION_PROFILE_ADDED: {
      auto* registry =
          ExtensionRegistry::Get(content::Source<Profile>(source).ptr());
      DCHECK(!extension_registry_observer_.IsObserving(registry));
      extension_registry_observer_.Add(registry);
      break;
    }
    case chrome::NOTIFICATION_PROFILE_DESTROYED: {
      Profile* profile = content::Source<Profile>(source).ptr();
      BrowserThread::PostTask(
          BrowserThread::IO, FROM_HERE,
          base::BindOnce(&UserScriptListener::ProfileDestroyed, this, profile));
      break;
    }
    case extensions::NOTIFICATION_USER_SCRIPTS_UPDATED: {
      Profile* profile = content::Source<Profile>(source).ptr();
      BrowserThread::PostTask(
          BrowserThread::IO, FROM_HERE,
          base::BindOnce(&UserScriptListener::UserScriptsReady, this, profile));
      break;
    }
    default:
      NOTREACHED();
  }
}

void UserScriptListener::OnExtensionLoaded(
    content::BrowserContext* browser_context,
    const Extension* extension) {
  if (ContentScriptsInfo::GetContentScripts(extension).empty())
    return;  // no new patterns from this extension.

  URLPatterns new_patterns;
  CollectURLPatterns(extension, &new_patterns);
  if (!new_patterns.empty()) {
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::BindOnce(&UserScriptListener::AppendNewURLPatterns, this,
                       browser_context, new_patterns));
  }
}

void UserScriptListener::OnExtensionUnloaded(
    content::BrowserContext* browser_context,
    const Extension* extension,
    UnloadedExtensionReason reason) {
  if (ContentScriptsInfo::GetContentScripts(extension).empty())
    return;  // No patterns to delete for this extension.

  // Clear all our patterns and reregister all the still-loaded extensions.
  const ExtensionSet& extensions =
      ExtensionRegistry::Get(browser_context)->enabled_extensions();
  URLPatterns new_patterns;
  for (ExtensionSet::const_iterator it = extensions.begin();
       it != extensions.end(); ++it) {
    if (it->get() != extension)
      CollectURLPatterns(it->get(), &new_patterns);
  }
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::BindOnce(&UserScriptListener::ReplaceURLPatterns, this,
                     browser_context, new_patterns));
}

void UserScriptListener::OnShutdown(ExtensionRegistry* registry) {
  extension_registry_observer_.Remove(registry);
}

}  // namespace extensions
