// 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/automation/automation_provider.h"

#include <set>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/file_path.h"
#include "base/json/json_reader.h"
#include "base/json/json_string_value_serializer.h"
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/stl_util.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/automation/automation_browser_tracker.h"
#include "chrome/browser/automation/automation_provider_list.h"
#include "chrome/browser/automation/automation_provider_observers.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/automation/automation_tab_tracker.h"
#include "chrome/browser/automation/automation_window_tracker.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_storage.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/printing/print_job.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ssl/ssl_blocking_page.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/find_bar/find_notification_details.h"
#include "chrome/browser/ui/find_bar/find_tab_helper.h"
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/common/automation_constants.h"
#include "chrome/common/automation_messages.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/trace_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
#endif  // defined(OS_CHROMEOS)

using WebKit::WebFindOptions;
using base::Time;
using content::BrowserThread;
using content::DownloadItem;
using content::NavigationController;
using content::RenderViewHost;
using content::TraceController;
using content::WebContents;

namespace {

void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
  DCHECK(pc);
  bool no_proxy = false;
  if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
    // Make no changes to the ProxyConfig.
    return;
  }
  bool auto_config;
  if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
    pc->set_auto_detect(true);
  }
  std::string pac_url;
  if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
    pc->set_pac_url(GURL(pac_url));
  }
  bool pac_mandatory;
  if (dict.GetBoolean(automation::kJSONProxyPacMandatory, &pac_mandatory)) {
    pc->set_pac_mandatory(pac_mandatory);
  }
  std::string proxy_bypass_list;
  if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
    pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
  }
  std::string proxy_server;
  if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
    pc->proxy_rules().ParseFromString(proxy_server);
  }
}

void SetProxyConfigCallback(
    const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
    const std::string& proxy_config) {
  // First, deserialize the JSON string. If this fails, log and bail.
  JSONStringValueSerializer deserializer(proxy_config);
  std::string error_msg;
  scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
  if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
    DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
                  << error_msg;
    return;
  }

  scoped_ptr<DictionaryValue> dict(
      static_cast<DictionaryValue*>(root.release()));
  // Now put together a proxy configuration from the deserialized string.
  net::ProxyConfig pc;
  PopulateProxyConfig(*dict.get(), &pc);

  net::ProxyService* proxy_service =
      request_context_getter->GetURLRequestContext()->proxy_service();
  DCHECK(proxy_service);
  scoped_ptr<net::ProxyConfigService> proxy_config_service(
      new net::ProxyConfigServiceFixed(pc));
  proxy_service->ResetConfigService(proxy_config_service.release());
}

}  // namespace

AutomationProvider::AutomationProvider(Profile* profile)
    : profile_(profile),
      reply_message_(NULL),
      reinitialize_on_channel_error_(
          CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kAutomationReinitializeOnChannelError)),
      use_initial_load_observers_(true),
      is_connected_(false),
      initial_tab_loads_complete_(false),
      network_library_initialized_(true),
      login_webui_ready_(true) {
  TRACE_EVENT_BEGIN_ETW("AutomationProvider::AutomationProvider", 0, "");

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  browser_tracker_.reset(new AutomationBrowserTracker(this));
  tab_tracker_.reset(new AutomationTabTracker(this));
  window_tracker_.reset(new AutomationWindowTracker(this));
  new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this, profile));
  metric_event_duration_observer_.reset(new MetricEventDurationObserver());

  TRACE_EVENT_END_ETW("AutomationProvider::AutomationProvider", 0, "");
}

AutomationProvider::~AutomationProvider() {
  if (channel_.get())
    channel_->Close();
}

void AutomationProvider::set_profile(Profile* profile) {
  profile_ = profile;
}

bool AutomationProvider::InitializeChannel(const std::string& channel_id) {
  TRACE_EVENT_BEGIN_ETW("AutomationProvider::InitializeChannel", 0, "");

  channel_id_ = channel_id;
  std::string effective_channel_id = channel_id;

  // If the channel_id starts with kNamedInterfacePrefix, create a named IPC
  // server and listen on it, else connect as client to an existing IPC server
  bool use_named_interface =
      channel_id.find(automation::kNamedInterfacePrefix) == 0;
  if (use_named_interface) {
    effective_channel_id = channel_id.substr(
        strlen(automation::kNamedInterfacePrefix));
    if (effective_channel_id.length() <= 0)
      return false;

    reinitialize_on_channel_error_ = true;
  }

  if (!automation_resource_message_filter_.get()) {
    automation_resource_message_filter_ = new AutomationResourceMessageFilter;
  }

  channel_.reset(new IPC::ChannelProxy(
      effective_channel_id,
      GetChannelMode(use_named_interface),
      this,
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
  channel_->AddFilter(automation_resource_message_filter_);

#if defined(OS_CHROMEOS)
  if (use_initial_load_observers_) {
    // Wait for webui login to be ready.
    // Observer will delete itself.
    if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kLoginManager) &&
        !chromeos::UserManager::Get()->IsUserLoggedIn()) {
      login_webui_ready_ = false;
      new OOBEWebuiReadyObserver(this);
    }

    // Wait for the network manager to initialize.
    // The observer will delete itself when done.
    network_library_initialized_ = false;
    NetworkManagerInitObserver* observer = new NetworkManagerInitObserver(this);
    if (!observer->Init())
      delete observer;
  }
#endif

  TRACE_EVENT_END_ETW("AutomationProvider::InitializeChannel", 0, "");

  return true;
}

IPC::Channel::Mode AutomationProvider::GetChannelMode(
    bool use_named_interface) {
  if (use_named_interface)
    return IPC::Channel::MODE_NAMED_SERVER;
  else
    return IPC::Channel::MODE_CLIENT;
}

std::string AutomationProvider::GetProtocolVersion() {
  chrome::VersionInfo version_info;
  return version_info.Version().c_str();
}

void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
  VLOG(2) << "SetExpectedTabCount:" << expected_tabs;
  if (expected_tabs == 0)
    OnInitialTabLoadsComplete();
  else
    initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
}

void AutomationProvider::OnInitialTabLoadsComplete() {
  initial_tab_loads_complete_ = true;
  VLOG(2) << "OnInitialTabLoadsComplete";
  SendInitialLoadMessage();
}

void AutomationProvider::OnNetworkLibraryInit() {
  network_library_initialized_ = true;
  VLOG(2) << "OnNetworkLibraryInit";
  SendInitialLoadMessage();
}

void AutomationProvider::OnOOBEWebuiReady() {
  login_webui_ready_ = true;
  VLOG(2) << "OnOOBEWebuiReady";
  SendInitialLoadMessage();
}

void AutomationProvider::SendInitialLoadMessage() {
  if (is_connected_ && initial_tab_loads_complete_ &&
      network_library_initialized_ && login_webui_ready_) {
    VLOG(2) << "Initial loads complete; sending initial loads message.";
    Send(new AutomationMsg_InitialLoadsComplete());
  }
}

void AutomationProvider::DisableInitialLoadObservers() {
  use_initial_load_observers_ = false;
  OnInitialTabLoadsComplete();
  OnNetworkLibraryInit();
  OnOOBEWebuiReady();
}

int AutomationProvider::GetIndexForNavigationController(
    const NavigationController* controller, const Browser* parent) const {
  DCHECK(parent);
  return parent->tab_strip_model()->GetIndexOfWebContents(
      controller->GetWebContents());
}

// TODO(phajdan.jr): move to TestingAutomationProvider.
DictionaryValue* AutomationProvider::GetDictionaryFromDownloadItem(
    const DownloadItem* download, bool incognito) {
  std::map<DownloadItem::DownloadState, std::string> state_to_string;
  state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
  state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
  state_to_string[DownloadItem::INTERRUPTED] = std::string("INTERRUPTED");
  state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");

  std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
  safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
  safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
  safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
      std::string("DANGEROUS_BUT_VALIDATED");

  DictionaryValue* dl_item_value = new DictionaryValue;
  dl_item_value->SetInteger("id", static_cast<int>(download->GetId()));
  dl_item_value->SetString("url", download->GetURL().spec());
  dl_item_value->SetString("referrer_url", download->GetReferrerUrl().spec());
  dl_item_value->SetString("file_name",
                           download->GetFileNameToReportUser().value());
  dl_item_value->SetString("full_path",
                           download->GetTargetFilePath().value());
  dl_item_value->SetBoolean("is_paused", download->IsPaused());
  dl_item_value->SetBoolean("open_when_complete",
                            download->GetOpenWhenComplete());
  dl_item_value->SetBoolean("is_temporary", download->IsTemporary());
  dl_item_value->SetBoolean("is_otr", incognito);
  dl_item_value->SetString("state", state_to_string[download->GetState()]);
  dl_item_value->SetString("safety_state",
                           safety_state_to_string[download->GetSafetyState()]);
  dl_item_value->SetInteger("PercentComplete", download->PercentComplete());

  return dl_item_value;
}

void AutomationProvider::OnChannelConnected(int pid) {
  is_connected_ = true;

  // Send a hello message with our current automation protocol version.
  VLOG(2) << "Testing channel connected, sending hello message";
  channel_->Send(new AutomationMsg_Hello(GetProtocolVersion()));

  SendInitialLoadMessage();
}

void AutomationProvider::OnEndTracingComplete() {
  IPC::Message* reply_message = tracing_data_.reply_message.release();
  if (reply_message) {
    AutomationMsg_EndTracing::WriteReplyParams(
        reply_message, tracing_data_.trace_output.size(), true);
    Send(reply_message);
  }
}

void AutomationProvider::OnTraceDataCollected(
    const scoped_refptr<base::RefCountedString>& trace_fragment) {
  tracing_data_.trace_output.push_back(trace_fragment->data());
}

bool AutomationProvider::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  bool deserialize_success = true;
  IPC_BEGIN_MESSAGE_MAP_EX(AutomationProvider, message, deserialize_success)
#if !defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
                                    WindowSimulateDrag)
#endif  // !defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
    IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig)
    IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
    IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
    IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
    IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
    IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
    IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
    IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
    IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
    IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
    IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
    IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
    IPC_MESSAGE_HANDLER(AutomationMsg_JavaScriptStressTestControl,
                        JavaScriptStressTestControl)
    IPC_MESSAGE_HANDLER(AutomationMsg_BeginTracing, BeginTracing)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EndTracing, EndTracing)
    IPC_MESSAGE_HANDLER(AutomationMsg_GetTracingOutput, GetTracingOutput)
#if defined(OS_WIN) && !defined(USE_AURA)
    // These are for use with external tabs.
    IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
    IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
                        ProcessUnhandledAccelerator)
    IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
    IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
    IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
                        OnForwardContextMenuCommandToChrome)
    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
                        NavigateInExternalTab)
    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
                        NavigateExternalTabAtIndex)
    IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
    IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
                        OnMessageFromExternalHost)
    IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RunUnloadHandlers,
                                    OnRunUnloadHandlers)
    IPC_MESSAGE_HANDLER(AutomationMsg_SetZoomLevel, OnSetZoomLevel)
#endif  // defined(OS_WIN)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  if (!handled)
    OnUnhandledMessage(message);
  if (!deserialize_success)
    OnMessageDeserializationFailure();
  return handled;
}

void AutomationProvider::OnUnhandledMessage(const IPC::Message& message) {
  // We should not hang here. Print a message to indicate what's going on,
  // and disconnect the channel to notify the caller about the error
  // in a way it can't ignore, and make any further attempts to send
  // messages fail fast.
  LOG(ERROR) << "AutomationProvider received a message it can't handle. "
             << "Message type: " << message.type()
             << ", routing ID: " << message.routing_id() << ". "
             << "Please make sure that you use switches::kTestingChannelID "
             << "for test code (TestingAutomationProvider), and "
             << "switches::kAutomationClientChannelID for everything else "
             << "(like ChromeFrame). Closing the automation channel.";
  channel_->Close();
}

void AutomationProvider::OnMessageDeserializationFailure() {
  LOG(ERROR) << "Failed to deserialize IPC message. "
             << "Closing the automation channel.";
  channel_->Close();
}

void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
  if (window_tracker_->ContainsHandle(handle)) {
    window_tracker_->Remove(window_tracker_->GetResource(handle));
  }
}

bool AutomationProvider::ReinitializeChannel() {
  base::ThreadRestrictions::ScopedAllowIO allow_io;

  // Make sure any old channels are cleaned up before starting up a new one.
  channel_.reset();
  return InitializeChannel(channel_id_);
}

void AutomationProvider::OnChannelError() {
  if (reinitialize_on_channel_error_) {
    VLOG(1) << "AutomationProxy disconnected, resetting AutomationProvider.";
    if (ReinitializeChannel())
      return;
    VLOG(1) << "Error reinitializing AutomationProvider channel.";
  }
  VLOG(1) << "AutomationProxy went away, shutting down app.";
  g_browser_process->GetAutomationProviderList()->RemoveProvider(this);
}

bool AutomationProvider::Send(IPC::Message* msg) {
  DCHECK(channel_.get());
  return channel_->Send(msg);
}

Browser* AutomationProvider::FindAndActivateTab(
    NavigationController* controller) {
  content::WebContentsDelegate* d = controller->GetWebContents()->GetDelegate();
  if (d)
    d->ActivateContents(controller->GetWebContents());
  return browser::FindBrowserWithWebContents(controller->GetWebContents());
}

void AutomationProvider::HandleFindRequest(
    int handle,
    const AutomationMsg_Find_Params& params,
    IPC::Message* reply_message) {
  if (!tab_tracker_->ContainsHandle(handle)) {
    AutomationMsg_Find::WriteReplyParams(reply_message, -1, -1);
    Send(reply_message);
    return;
  }

  NavigationController* nav = tab_tracker_->GetResource(handle);
  WebContents* web_contents = nav->GetWebContents();

  SendFindRequest(web_contents,
                  false,
                  params.search_string,
                  params.forward,
                  params.match_case,
                  params.find_next,
                  reply_message);
}

void AutomationProvider::SendFindRequest(
    WebContents* web_contents,
    bool with_json,
    const string16& search_string,
    bool forward,
    bool match_case,
    bool find_next,
    IPC::Message* reply_message) {
  int request_id = FindInPageNotificationObserver::kFindInPageRequestId;
  FindInPageNotificationObserver* observer =
      new FindInPageNotificationObserver(this,
                                         web_contents,
                                         with_json,
                                         reply_message);
  if (!with_json) {
    find_in_page_observer_.reset(observer);
  }
  FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
  if (find_tab_helper)
    find_tab_helper->set_current_find_request_id(request_id);

  WebFindOptions options;
  options.forward = forward;
  options.matchCase = match_case;
  options.findNext = find_next;
  web_contents->GetRenderViewHost()->Find(
      FindInPageNotificationObserver::kFindInPageRequestId, search_string,
      options);
}

void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
  net::URLRequestContextGetter* context_getter =
      profile_->GetRequestContext();
  DCHECK(context_getter);

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(SetProxyConfigCallback, make_scoped_refptr(context_getter),
                 new_proxy_config));
}

WebContents* AutomationProvider::GetWebContentsForHandle(
    int handle, NavigationController** tab) {
  if (tab_tracker_->ContainsHandle(handle)) {
    NavigationController* nav_controller = tab_tracker_->GetResource(handle);
    if (tab)
      *tab = nav_controller;
    return nav_controller->GetWebContents();
  }
  return NULL;
}

// Gets the current used encoding name of the page in the specified tab.
void AutomationProvider::OverrideEncoding(int tab_handle,
                                          const std::string& encoding_name,
                                          bool* success) {
  *success = false;
  if (tab_tracker_->ContainsHandle(tab_handle)) {
    NavigationController* nav = tab_tracker_->GetResource(tab_handle);
    if (!nav)
      return;
    Browser* browser = FindAndActivateTab(nav);

    // If the browser has UI, simulate what a user would do.
    // Activate the tab and then click the encoding menu.
    if (browser && chrome::IsCommandEnabled(browser, IDC_ENCODING_MENU)) {
      int selected_encoding_id =
          CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
      if (selected_encoding_id) {
        browser->OverrideEncoding(selected_encoding_id);
        *success = true;
      }
    } else {
      // There is no UI, Chrome probably runs as Chrome-Frame mode.
      // Try to get WebContents and call its override_encoding method.
      WebContents* contents = nav->GetWebContents();
      if (!contents)
        return;
      const std::string selected_encoding =
          CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
      if (selected_encoding.empty())
        return;
      contents->SetOverrideEncoding(selected_encoding);
    }
  }
}

void AutomationProvider::SelectAll(int tab_handle) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    NOTREACHED();
    return;
  }

  view->SelectAll();
}

void AutomationProvider::Cut(int tab_handle) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    NOTREACHED();
    return;
  }

  view->Cut();
}

void AutomationProvider::Copy(int tab_handle) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    NOTREACHED();
    return;
  }

  view->Copy();
}

void AutomationProvider::Paste(int tab_handle) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    NOTREACHED();
    return;
  }

  view->Paste();
}

void AutomationProvider::ReloadAsync(int tab_handle) {
  if (tab_tracker_->ContainsHandle(tab_handle)) {
    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
    if (!tab) {
      NOTREACHED();
      return;
    }

    const bool check_for_repost = true;
    tab->Reload(check_for_repost);
  }
}

void AutomationProvider::StopAsync(int tab_handle) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    // We tolerate StopAsync being called even before a view has been created.
    // So just log a warning instead of a NOTREACHED().
    DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
    return;
  }

  view->Stop();
}

void AutomationProvider::OnSetPageFontSize(int tab_handle,
                                           int font_size) {
  AutomationPageFontSize automation_font_size =
      static_cast<AutomationPageFontSize>(font_size);

  if (automation_font_size < SMALLEST_FONT ||
      automation_font_size > LARGEST_FONT) {
      DLOG(ERROR) << "Invalid font size specified : "
                  << font_size;
      return;
  }

  if (tab_tracker_->ContainsHandle(tab_handle)) {
    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
    DCHECK(tab != NULL);
    if (tab && tab->GetWebContents()) {
      DCHECK(tab->GetWebContents()->GetBrowserContext() != NULL);
      Profile* profile = Profile::FromBrowserContext(
          tab->GetWebContents()->GetBrowserContext());
      profile->GetPrefs()->SetInteger(prefs::kWebKitDefaultFontSize, font_size);
    }
  }
}

void AutomationProvider::RemoveBrowsingData(int remove_mask) {
  BrowsingDataRemover* remover;
  remover = BrowsingDataRemover::CreateForUnboundedRange(profile());
  remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
  // BrowsingDataRemover deletes itself.
}

void AutomationProvider::JavaScriptStressTestControl(int tab_handle,
                                                     int cmd,
                                                     int param) {
  RenderViewHost* view = GetViewForTab(tab_handle);
  if (!view) {
    NOTREACHED();
    return;
  }

  view->Send(new ChromeViewMsg_JavaScriptStressTestControl(
      view->GetRoutingID(), cmd, param));
}

void AutomationProvider::BeginTracing(const std::string& categories,
                                      bool* success) {
  tracing_data_.trace_output.clear();
  *success = TraceController::GetInstance()->BeginTracing(this, categories);
}

void AutomationProvider::EndTracing(IPC::Message* reply_message) {
  bool success = false;
  if (!tracing_data_.reply_message.get())
    success = TraceController::GetInstance()->EndTracingAsync(this);
  if (success) {
    // Defer EndTracing reply until TraceController calls us back with all the
    // events.
    tracing_data_.reply_message.reset(reply_message);
  } else {
    // If failed to call EndTracingAsync, need to reply with failure now.
    AutomationMsg_EndTracing::WriteReplyParams(reply_message, size_t(0), false);
    Send(reply_message);
  }
}

void AutomationProvider::GetTracingOutput(std::string* chunk,
                                          bool* success) {
  // The JSON data is sent back to the test in chunks, because IPC sends will
  // fail if they are too large.
  if (tracing_data_.trace_output.empty()) {
    *chunk = "";
    *success = false;
  } else {
    *chunk = tracing_data_.trace_output.front();
    tracing_data_.trace_output.pop_front();
    *success = true;
  }
}

RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
  if (tab_tracker_->ContainsHandle(tab_handle)) {
    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
    if (!tab) {
      NOTREACHED();
      return NULL;
    }

    WebContents* web_contents = tab->GetWebContents();
    if (!web_contents) {
      NOTREACHED();
      return NULL;
    }

    RenderViewHost* view_host = web_contents->GetRenderViewHost();
    return view_host;
  }

  return NULL;
}

void AutomationProvider::SaveAsAsync(int tab_handle) {
  NavigationController* tab = NULL;
  WebContents* web_contents = GetWebContentsForHandle(tab_handle, &tab);
  if (web_contents)
    web_contents->OnSavePage();
}
