// Copyright 2014 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 "extensions/renderer/user_script_set_manager.h"

#include "components/crx_file/id_util.h"
#include "content/public/renderer/render_thread.h"
#include "extensions/common/extension_messages.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/script_injection.h"
#include "extensions/renderer/user_script_set.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"

namespace extensions {

UserScriptSetManager::UserScriptSetManager()
    : activity_logging_enabled_(false) {
  content::RenderThread::Get()->AddObserver(this);
}

UserScriptSetManager::~UserScriptSetManager() {
}

void UserScriptSetManager::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void UserScriptSetManager::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

std::unique_ptr<ScriptInjection>
UserScriptSetManager::GetInjectionForDeclarativeScript(
    int script_id,
    content::RenderFrame* render_frame,
    int tab_id,
    const GURL& url,
    const std::string& extension_id) {
  UserScriptSet* user_script_set =
      GetProgrammaticScriptsByHostID(HostID(HostID::EXTENSIONS, extension_id));
  if (!user_script_set)
    return std::unique_ptr<ScriptInjection>();

  return user_script_set->GetDeclarativeScriptInjection(
      script_id, render_frame, tab_id, UserScript::BROWSER_DRIVEN, url,
      activity_logging_enabled_);
}

bool UserScriptSetManager::OnControlMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(UserScriptSetManager, message)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void UserScriptSetManager::GetAllInjections(
    std::vector<std::unique_ptr<ScriptInjection>>* injections,
    content::RenderFrame* render_frame,
    int tab_id,
    UserScript::RunLocation run_location) {
  static_scripts_.GetInjections(injections, render_frame, tab_id, run_location,
                                activity_logging_enabled_);
  for (auto it = programmatic_scripts_.begin();
       it != programmatic_scripts_.end(); ++it) {
    it->second->GetInjections(injections, render_frame, tab_id, run_location,
                              activity_logging_enabled_);
  }
}

void UserScriptSetManager::GetAllActiveExtensionIds(
    std::set<std::string>* ids) const {
  DCHECK(ids);
  static_scripts_.GetActiveExtensionIds(ids);
  for (auto it = programmatic_scripts_.cbegin();
       it != programmatic_scripts_.cend(); ++it) {
    it->second->GetActiveExtensionIds(ids);
  }
}

UserScriptSet* UserScriptSetManager::GetProgrammaticScriptsByHostID(
    const HostID& host_id) {
  UserScriptSetMap::const_iterator it = programmatic_scripts_.find(host_id);
  return it != programmatic_scripts_.end() ? it->second.get() : NULL;
}

void UserScriptSetManager::OnUpdateUserScripts(
    base::SharedMemoryHandle shared_memory,
    const HostID& host_id,
    const std::set<HostID>& changed_hosts,
    bool whitelisted_only) {
  if (!base::SharedMemory::IsHandleValid(shared_memory)) {
    NOTREACHED() << "Bad scripts handle";
    return;
  }

  for (const HostID& host_id : changed_hosts) {
    if (host_id.type() == HostID::EXTENSIONS &&
        !crx_file::id_util::IdIsValid(host_id.id())) {
      NOTREACHED() << "Invalid extension id: " << host_id.id();
      return;
    }
  }

  UserScriptSet* scripts = NULL;
  if (!host_id.id().empty()) {
    // The expectation when there is a host that "owns" this shared
    // memory region is that the |changed_hosts| is either the empty list
    // or just the owner.
    CHECK(changed_hosts.size() <= 1);
    if (programmatic_scripts_.find(host_id) == programmatic_scripts_.end()) {
      scripts = programmatic_scripts_
                    .insert(std::make_pair(host_id,
                                           std::make_unique<UserScriptSet>()))
                    .first->second.get();
    } else {
      scripts = programmatic_scripts_[host_id].get();
    }
  } else {
    scripts = &static_scripts_;
  }
  DCHECK(scripts);

  // If no hosts are included in the set, that indicates that all
  // hosts were updated. Add them all to the set so that observers and
  // individual UserScriptSets don't need to know this detail.
  const std::set<HostID>* effective_hosts = &changed_hosts;
  std::set<HostID> all_hosts;
  if (changed_hosts.empty()) {
    // The meaning of "all hosts(extensions)" varies, depending on whether some
    // host "owns" this shared memory region.
    // No owner => all known hosts.
    // Owner    => just the owner host.
    if (host_id.id().empty()) {
      std::set<std::string> extension_ids =
          RendererExtensionRegistry::Get()->GetIDs();
      for (const std::string& extension_id : extension_ids)
        all_hosts.insert(HostID(HostID::EXTENSIONS, extension_id));
    } else {
      all_hosts.insert(host_id);
    }
    effective_hosts = &all_hosts;
  }

  if (scripts->UpdateUserScripts(shared_memory,
                                 *effective_hosts,
                                 whitelisted_only)) {
    for (auto& observer : observers_)
      observer.OnUserScriptsUpdated(*effective_hosts);
  }
}

}  // namespace extensions
