// 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.

#ifndef CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_
#define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_

#include <map>
#include <string>

#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/strings/string_piece.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_set.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/common/user_script.h"

namespace content {
class RenderProcessHost;
}

class Profile;

typedef std::map<std::string, ExtensionSet::ExtensionPathAndDefaultLocale>
    ExtensionsInfo;

namespace extensions {

// Manages a segment of shared memory that contains the user scripts the user
// has installed.  Lives on the UI thread.
class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
                         public content::NotificationObserver {
 public:
  explicit UserScriptMaster(Profile* profile);

  // Kicks off a process on the file thread to reload scripts from disk
  // into a new chunk of shared memory and notify renderers.
  virtual void StartLoad();

  // Gets the segment of shared memory for the scripts.
  base::SharedMemory* GetSharedMemory() const {
    return shared_memory_.get();
  }

  // Called by the script reloader when new scripts have been loaded.
  void NewScriptsAvailable(base::SharedMemory* handle);

  // Return true if we have any scripts ready.
  bool ScriptsReady() const { return shared_memory_.get() != NULL; }

 protected:
  friend class base::RefCountedThreadSafe<UserScriptMaster>;

  virtual ~UserScriptMaster();

 public:
  // We reload user scripts on the file thread to prevent blocking the UI.
  // ScriptReloader lives on the file thread and does the reload
  // work, and then sends a message back to its master with a new SharedMemory*.
  // ScriptReloader is the worker that manages running the script load
  // on the file thread. It must be created on, and its public API must only be
  // called from, the master's thread.
  class ScriptReloader
      : public base::RefCountedThreadSafe<UserScriptMaster::ScriptReloader> {
   public:
    // Parses the includes out of |script| and returns them in |includes|.
    static bool ParseMetadataHeader(const base::StringPiece& script_text,
                                    UserScript* script);

    explicit ScriptReloader(UserScriptMaster* master);

    // Start loading of scripts.
    // Will always send a message to the master upon completion.
    void StartLoad(const UserScriptList& external_scripts,
                   const ExtensionsInfo& extension_info_);

    // The master is going away; don't call it back.
    void DisownMaster() {
      master_ = NULL;
    }

   private:
    FRIEND_TEST_ALL_PREFIXES(UserScriptMasterTest, SkipBOMAtTheBeginning);
    FRIEND_TEST_ALL_PREFIXES(UserScriptMasterTest, LeaveBOMNotAtTheBeginning);
    friend class base::RefCountedThreadSafe<UserScriptMaster::ScriptReloader>;

    ~ScriptReloader();

    // Where functions are run:
    //    master          file
    //   StartLoad   ->  RunLoad
    //                     LoadUserScripts()
    // NotifyMaster  <-  RunLoad

    // Runs on the master thread.
    // Notify the master that new scripts are available.
    void NotifyMaster(base::SharedMemory* memory);

    // Runs on the File thread.
    // Load the specified user scripts, calling NotifyMaster when done.
    // |user_scripts| is intentionally passed by value so its lifetime isn't
    // tied to the caller.
    void RunLoad(const UserScriptList& user_scripts);

    void LoadUserScripts(UserScriptList* user_scripts);

    // Uses extensions_info_ to build a map of localization messages.
    // Returns NULL if |extension_id| is invalid.
    SubstitutionMap* GetLocalizationMessages(std::string extension_id);

    // A pointer back to our master.
    // May be NULL if DisownMaster() is called.
    UserScriptMaster* master_;

    // Maps extension info needed for localization to an extension ID.
    ExtensionsInfo extensions_info_;

    // The message loop to call our master back on.
    // Expected to always outlive us.
    content::BrowserThread::ID master_thread_id_;

    DISALLOW_COPY_AND_ASSIGN(ScriptReloader);
  };

 private:
  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // Sends the renderer process a new set of user scripts.
  void SendUpdate(content::RenderProcessHost* process,
                  base::SharedMemory* shared_memory);

  // Manages our notification registrations.
  content::NotificationRegistrar registrar_;

  // We hang on to our pointer to know if we've already got one running.
  scoped_refptr<ScriptReloader> script_reloader_;

  // Contains the scripts that were found the last time scripts were updated.
  scoped_ptr<base::SharedMemory> shared_memory_;

  // List of scripts from currently-installed extensions we should load.
  UserScriptList user_scripts_;

  // Maps extension info needed for localization to an extension ID.
  ExtensionsInfo extensions_info_;

  // If the extensions service has finished loading its initial set of
  // extensions.
  bool extensions_service_ready_;

  // If list of user scripts is modified while we're loading it, we note
  // that we're currently mid-load and then start over again once the load
  // finishes.  This boolean tracks whether another load is pending.
  bool pending_load_;

  // The profile for which the scripts managed here are installed.
  Profile* profile_;

  DISALLOW_COPY_AND_ASSIGN(UserScriptMaster);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_MASTER_H_
