// 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/printing/print_dialog_cloud.h"


#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/json/json_reader.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/printing/print_dialog_cloud_internal.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/print_messages.h"
#include "chrome/common/url_constants.h"
#include "components/cloud_devices/common/cloud_devices_urls.h"
#include "components/google/core/browser/google_util.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/web_preferences.h"

#if defined(USE_AURA)
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#endif

#if defined(OS_WIN)
#include "ui/base/win/foreground_helper.h"
#endif

// This module implements the UI support in Chrome for cloud printing.
// This means hosting a dialog containing HTML/JavaScript and using
// the published cloud print user interface integration APIs to get
// page setup settings from the dialog contents and provide the
// generated print data to the dialog contents for uploading to the
// cloud print service.

// Currently, the flow between these classes is as follows:

// PrintDialogCloud::CreatePrintDialogForFile is called from
// resource_message_filter_gtk.cc once the renderer has informed the
// renderer host that print data generation into the renderer host provided
// temp file has been completed.  That call is on the FILE thread.
// That, in turn, hops over to the UI thread to create an instance of
// PrintDialogCloud.

// The constructor for PrintDialogCloud creates a
// CloudPrintWebDialogDelegate and asks the current active browser to
// show an HTML dialog using that class as the delegate. That class
// hands in the kChromeUICloudPrintResourcesURL as the URL to visit.  That is
// recognized by the GetWebUIFactoryFunction as a signal to create an
// ExternalWebDialogUI.

// CloudPrintWebDialogDelegate also temporarily owns a
// CloudPrintFlowHandler, a class which is responsible for the actual
// interactions with the dialog contents, including handing in the
// print data and getting any page setup parameters that the dialog
// contents provides.  As part of bringing up the dialog,
// WebDialogUI::RenderViewCreated is called (an override of
// WebUI::RenderViewCreated).  That routine, in turn, calls the
// delegate's GetWebUIMessageHandlers routine, at which point the
// ownership of the CloudPrintFlowHandler is handed over.  A pointer
// to the flow handler is kept to facilitate communication back and
// forth between the two classes.

// The WebUI continues dialog bring-up, calling
// CloudPrintFlowHandler::RegisterMessages.  This is where the
// additional object model capabilities are registered for the dialog
// contents to use.  It is also at this time that capabilities for the
// dialog contents are adjusted to allow the dialog contents to close
// the window.  In addition, the pending URL is redirected to the
// actual cloud print service URL.  The flow controller also registers
// for notification of when the dialog contents finish loading, which
// is currently used to send the data to the dialog contents.

// In order to send the data to the dialog contents, the flow
// handler uses a CloudPrintDataSender.  It creates one, letting it
// know the name of the temporary file containing the data, and
// posts the task of reading the file
// (CloudPrintDataSender::ReadPrintDataFile) to the file thread.  That
// routine reads in the file, and then hops over to the IO thread to
// send that data to the dialog contents.

// When the dialog contents are finished (by either being cancelled or
// hitting the print button), the delegate is notified, and responds
// that the dialog should be closed, at which point things are torn
// down and released.

using content::BrowserThread;
using content::NavigationController;
using content::NavigationEntry;
using content::RenderViewHost;
using content::WebContents;
using content::WebPreferences;
using content::WebUIMessageHandler;
using ui::WebDialogDelegate;

namespace {

const int kDefaultWidth = 912;
const int kDefaultHeight = 633;

bool IsSimilarUrl(const GURL& url, const GURL& cloud_print_url) {
  return url.host() == cloud_print_url.host() &&
         StartsWithASCII(url.path(), cloud_print_url.path(), false) &&
         url.scheme() == cloud_print_url.scheme();
}

class SignInObserver : public content::WebContentsObserver {
 public:
  SignInObserver(content::WebContents* web_contents,
                 GURL cloud_print_url,
                 const base::Closure& callback)
      : WebContentsObserver(web_contents),
        cloud_print_url_(cloud_print_url),
        callback_(callback),
        weak_ptr_factory_(this) {
  }

 private:
  // Overridden from content::WebContentsObserver:
  virtual void DidNavigateMainFrame(
      const content::LoadCommittedDetails& details,
      const content::FrameNavigateParams& params) OVERRIDE {
    if (IsSimilarUrl(params.url, cloud_print_url_)) {
      base::MessageLoop::current()->PostTask(
          FROM_HERE,
          base::Bind(&SignInObserver::OnSignIn,
                     weak_ptr_factory_.GetWeakPtr()));
    }
  }

  virtual void WebContentsDestroyed() OVERRIDE {
    delete this;
  }

  void OnSignIn() {
    callback_.Run();
    if (web_contents())
      web_contents()->Close();
  }

  GURL cloud_print_url_;
  base::Closure callback_;
  base::WeakPtrFactory<SignInObserver> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SignInObserver);
};

}  // namespace

namespace internal_cloud_print_helpers {

// From the JSON parsed value, get the entries for the page setup
// parameters.
bool GetPageSetupParameters(const std::string& json,
                            PrintMsg_Print_Params& parameters) {
  scoped_ptr<base::Value> parsed_value(base::JSONReader::Read(json));
  DLOG_IF(ERROR, (!parsed_value.get() ||
                  !parsed_value->IsType(base::Value::TYPE_DICTIONARY)))
      << "PageSetup call didn't have expected contents";
  if (!parsed_value.get() ||
      !parsed_value->IsType(base::Value::TYPE_DICTIONARY)) {
    return false;
  }

  bool result = true;
  base::DictionaryValue* params =
      static_cast<base::DictionaryValue*>(parsed_value.get());
  result &= params->GetDouble("dpi", &parameters.dpi);
  result &= params->GetDouble("min_shrink", &parameters.min_shrink);
  result &= params->GetDouble("max_shrink", &parameters.max_shrink);
  result &= params->GetBoolean("selection_only", &parameters.selection_only);
  return result;
}

base::string16 GetSwitchValueString16(const CommandLine& command_line,
                                      const char* switchName) {
#if defined(OS_WIN)
  return command_line.GetSwitchValueNative(switchName);
#elif defined(OS_POSIX)
  // POSIX Command line string types are different.
  CommandLine::StringType native_switch_val;
  native_switch_val = command_line.GetSwitchValueASCII(switchName);
  // Convert the ASCII string to UTF16 to prepare to pass.
  return base::ASCIIToUTF16(native_switch_val);
#endif
}

void CloudPrintDataSenderHelper::CallJavascriptFunction(
    const std::string& function_name,
    const base::Value& arg1,
    const base::Value& arg2) {
  web_ui_->CallJavascriptFunction(function_name, arg1, arg2);
}

// Clears out the pointer we're using to communicate.  Either routine is
// potentially expensive enough that stopping whatever is in progress
// is worth it.
void CloudPrintDataSender::CancelPrintDataFile() {
  base::AutoLock lock(lock_);
  // We don't own helper, it was passed in to us, so no need to
  // delete, just let it go.
  helper_ = NULL;
}

CloudPrintDataSender::CloudPrintDataSender(
    CloudPrintDataSenderHelper* helper,
    const base::string16& print_job_title,
    const base::string16& print_ticket,
    const std::string& file_type,
    const base::RefCountedMemory* data)
    : helper_(helper),
      print_job_title_(print_job_title),
      print_ticket_(print_ticket),
      file_type_(file_type),
      data_(data) {
}

CloudPrintDataSender::~CloudPrintDataSender() {}

// We have the data in hand that needs to be pushed into the dialog
// contents; do so from the IO thread.

// TODO(scottbyer): If the print data ends up being larger than the
// upload limit (currently 10MB), what we need to do is upload that
// large data to google docs and set the URL in the printing
// JavaScript to that location, and make sure it gets deleted when not
// needed. - 4/1/2010
void CloudPrintDataSender::SendPrintData() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  if (!data_.get() || !data_->size())
    return;

  std::string base64_data;
  base::Base64Encode(
      base::StringPiece(data_->front_as<char>(), data_->size()),
      &base64_data);
  std::string header("data:");
  header.append(file_type_);
  header.append(";base64,");
  base64_data.insert(0, header);

  base::AutoLock lock(lock_);
  if (helper_) {
    base::StringValue title(print_job_title_);
    base::StringValue ticket(print_ticket_);
    // TODO(abodenha): Change Javascript call to pass in print ticket
    // after server side support is added. Add test for it.

    // Send the print data to the dialog contents.  The JavaScript
    // function is a preliminary API for prototyping purposes and is
    // subject to change.
    helper_->CallJavascriptFunction(
        "printApp._printDataUrl", base::StringValue(base64_data), title);
  }
}


CloudPrintFlowHandler::CloudPrintFlowHandler(
    const base::RefCountedMemory* data,
    const base::string16& print_job_title,
    const base::string16& print_ticket,
    const std::string& file_type)
    : dialog_delegate_(NULL),
      data_(data),
      print_job_title_(print_job_title),
      print_ticket_(print_ticket),
      file_type_(file_type) {
}

CloudPrintFlowHandler::~CloudPrintFlowHandler() {
  // This will also cancel any task in flight.
  CancelAnyRunningTask();
}


void CloudPrintFlowHandler::SetDialogDelegate(
    CloudPrintWebDialogDelegate* delegate) {
  // Even if setting a new WebUI, it means any previous task needs
  // to be canceled, its now invalid.
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  CancelAnyRunningTask();
  dialog_delegate_ = delegate;
}

// Cancels any print data sender we have in flight and removes our
// reference to it, so when the task that is calling it finishes and
// removes its reference, it goes away.
void CloudPrintFlowHandler::CancelAnyRunningTask() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (print_data_sender_.get()) {
    print_data_sender_->CancelPrintDataFile();
    print_data_sender_ = NULL;
  }
}

void CloudPrintFlowHandler::RegisterMessages() {
  // TODO(scottbyer) - This is where we will register messages for the
  // UI JS to use.  Needed: Call to update page setup parameters.
  web_ui()->RegisterMessageCallback("ShowDebugger",
      base::Bind(&CloudPrintFlowHandler::HandleShowDebugger,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("SendPrintData",
      base::Bind(&CloudPrintFlowHandler::HandleSendPrintData,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback("SetPageParameters",
      base::Bind(&CloudPrintFlowHandler::HandleSetPageParameters,
                 base::Unretained(this)));

  // Register for appropriate notifications, and re-direct the URL
  // to the real server URL, now that we've gotten an HTML dialog
  // going.
  NavigationController* controller =
      &web_ui()->GetWebContents()->GetController();
  NavigationEntry* pending_entry = controller->GetPendingEntry();
  if (pending_entry) {
    pending_entry->SetURL(google_util::AppendGoogleLocaleParam(
        cloud_devices::GetCloudPrintRelativeURL("client/dialog.html"),
        g_browser_process->GetApplicationLocale()));
  }
  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
                 content::Source<NavigationController>(controller));
  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
                 content::Source<NavigationController>(controller));
}

void CloudPrintFlowHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case content::NOTIFICATION_LOAD_STOP: {
      GURL url = web_ui()->GetWebContents()->GetURL();
      if (IsCloudPrintDialogUrl(url)) {
        // Take the opportunity to set some (minimal) additional
        // script permissions required for the web UI.
        RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
        if (rvh) {
          WebPreferences webkit_prefs = rvh->GetWebkitPreferences();
          webkit_prefs.allow_scripts_to_close_windows = true;
          rvh->UpdateWebkitPreferences(webkit_prefs);
        } else {
          NOTREACHED();
        }
        // Choose one or the other.  If you need to debug, bring up the
        // debugger.  You can then use the various chrome.send()
        // registrations above to kick of the various function calls,
        // including chrome.send("SendPrintData") in the javaScript
        // console and watch things happen with:
        // HandleShowDebugger(NULL);
        HandleSendPrintData(NULL);
      }
      break;
    }
  }
}

void CloudPrintFlowHandler::HandleShowDebugger(const base::ListValue* args) {
  ShowDebugger();
}

void CloudPrintFlowHandler::ShowDebugger() {
  if (web_ui()) {
    RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
    if (rvh)
      DevToolsWindow::OpenDevToolsWindow(rvh);
  }
}

scoped_refptr<CloudPrintDataSender>
CloudPrintFlowHandler::CreateCloudPrintDataSender() {
  DCHECK(web_ui());
  print_data_helper_.reset(new CloudPrintDataSenderHelper(web_ui()));
  scoped_refptr<CloudPrintDataSender> sender(
      new CloudPrintDataSender(print_data_helper_.get(),
                               print_job_title_,
                               print_ticket_,
                               file_type_,
                               data_.get()));
  return sender;
}

void CloudPrintFlowHandler::HandleSendPrintData(const base::ListValue* args) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  // This will cancel any ReadPrintDataFile() or SendPrintDataFile()
  // requests in flight (this is anticipation of when setting page
  // setup parameters becomes asynchronous and may be set while some
  // data is in flight).  Then we can clear out the print data.
  CancelAnyRunningTask();
  if (web_ui()) {
    print_data_sender_ = CreateCloudPrintDataSender();
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&CloudPrintDataSender::SendPrintData, print_data_sender_));
  }
}

void CloudPrintFlowHandler::HandleSetPageParameters(
    const base::ListValue* args) {
  std::string json;
  bool ret = args->GetString(0, &json);
  if (!ret || json.empty()) {
    NOTREACHED() << "Empty json string";
    return;
  }

  // These are backstop default values - 72 dpi to match the screen,
  // 8.5x11 inch paper with margins subtracted (1/4 inch top, left,
  // right and 0.56 bottom), and the min page shrink and max page
  // shrink values appear all over the place with no explanation.

  // TODO(scottbyer): Get a Linux/ChromeOS edge for PrintSettings
  // working so that we can get the default values from there.  Fix up
  // PrintWebViewHelper to do the same.
  const int kDPI = 72;
  const int kWidth = static_cast<int>((8.5-0.25-0.25)*kDPI);
  const int kHeight = static_cast<int>((11-0.25-0.56)*kDPI);
  const double kMinPageShrink = 1.25;
  const double kMaxPageShrink = 2.0;

  PrintMsg_Print_Params default_settings;
  default_settings.content_size = gfx::Size(kWidth, kHeight);
  default_settings.printable_area = gfx::Rect(0, 0, kWidth, kHeight);
  default_settings.dpi = kDPI;
  default_settings.min_shrink = kMinPageShrink;
  default_settings.max_shrink = kMaxPageShrink;
  default_settings.desired_dpi = kDPI;
  default_settings.document_cookie = 0;
  default_settings.selection_only = false;
  default_settings.preview_request_id = 0;
  default_settings.is_first_request = true;
  default_settings.print_to_pdf = false;

  if (!GetPageSetupParameters(json, default_settings)) {
    NOTREACHED();
    return;
  }

  // TODO(scottbyer) - Here is where we would kick the originating
  // renderer thread with these new parameters in order to get it to
  // re-generate the PDF data and hand it back to us.  window.print() is
  // currently synchronous, so there's a lot of work to do to get to
  // that point.
}

void CloudPrintFlowHandler::StoreDialogClientSize() const {
  if (web_ui() && web_ui()->GetWebContents()) {
    gfx::Size size = web_ui()->GetWebContents()->GetContainerBounds().size();
    Profile* profile = Profile::FromWebUI(web_ui());
    profile->GetPrefs()->SetInteger(prefs::kCloudPrintDialogWidth,
                                    size.width());
    profile->GetPrefs()->SetInteger(prefs::kCloudPrintDialogHeight,
                                    size.height());
  }
}

bool CloudPrintFlowHandler::IsCloudPrintDialogUrl(const GURL& url) {
  GURL cloud_print_url = cloud_devices::GetCloudPrintURL();
  return IsSimilarUrl(url, cloud_print_url);
}

CloudPrintWebDialogDelegate::CloudPrintWebDialogDelegate(
    content::BrowserContext* browser_context,
    gfx::NativeWindow modal_parent,
    const base::RefCountedMemory* data,
    const std::string& json_arguments,
    const base::string16& print_job_title,
    const base::string16& print_ticket,
    const std::string& file_type)
    : flow_handler_(
          new CloudPrintFlowHandler(data, print_job_title, print_ticket,
                                    file_type)),
      modal_parent_(modal_parent),
      owns_flow_handler_(true),
      keep_alive_when_non_modal_(true) {
  Init(browser_context, json_arguments);
}

// For unit testing.
CloudPrintWebDialogDelegate::CloudPrintWebDialogDelegate(
    CloudPrintFlowHandler* flow_handler,
    const std::string& json_arguments)
    : flow_handler_(flow_handler),
      modal_parent_(NULL),
      owns_flow_handler_(true),
      keep_alive_when_non_modal_(false) {
  Init(NULL, json_arguments);
}

// Returns the persisted width/height for the print dialog.
void GetDialogWidthAndHeightFromPrefs(content::BrowserContext* browser_context,
                                      int* width,
                                      int* height) {
  if (!browser_context) {
    *width = kDefaultWidth;
    *height = kDefaultHeight;
    return;
  }

  PrefService* prefs = Profile::FromBrowserContext(browser_context)->GetPrefs();
  *width = prefs->GetInteger(prefs::kCloudPrintDialogWidth);
  *height = prefs->GetInteger(prefs::kCloudPrintDialogHeight);
}

void CloudPrintWebDialogDelegate::Init(content::BrowserContext* browser_context,
                                       const std::string& json_arguments) {
  // This information is needed to show the dialog HTML content.
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  params_.url = GURL(chrome::kChromeUICloudPrintResourcesURL);
  GetDialogWidthAndHeightFromPrefs(browser_context,
                                   &params_.width,
                                   &params_.height);
  params_.json_input = json_arguments;

  flow_handler_->SetDialogDelegate(this);
  // If we're not modal we can show the dialog with no browser.
  // We need this to keep Chrome alive while our dialog is up.
  if (!modal_parent_ && keep_alive_when_non_modal_)
    chrome::IncrementKeepAliveCount();
}

CloudPrintWebDialogDelegate::~CloudPrintWebDialogDelegate() {
  // If the flow_handler_ is about to outlive us because we don't own
  // it anymore, we need to have it remove its reference to us.
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  flow_handler_->SetDialogDelegate(NULL);
  if (owns_flow_handler_) {
    delete flow_handler_;
  }
}

ui::ModalType CloudPrintWebDialogDelegate::GetDialogModalType() const {
    return modal_parent_ ? ui::MODAL_TYPE_WINDOW : ui::MODAL_TYPE_NONE;
}

base::string16 CloudPrintWebDialogDelegate::GetDialogTitle() const {
  return base::string16();
}

GURL CloudPrintWebDialogDelegate::GetDialogContentURL() const {
  return params_.url;
}

void CloudPrintWebDialogDelegate::GetWebUIMessageHandlers(
    std::vector<WebUIMessageHandler*>* handlers) const {
  handlers->push_back(flow_handler_);
  // We don't own flow_handler_ anymore, but it sticks around until at
  // least right after OnDialogClosed() is called (and this object is
  // destroyed).
  owns_flow_handler_ = false;
}

void CloudPrintWebDialogDelegate::GetDialogSize(gfx::Size* size) const {
  size->set_width(params_.width);
  size->set_height(params_.height);
}

std::string CloudPrintWebDialogDelegate::GetDialogArgs() const {
  return params_.json_input;
}

void CloudPrintWebDialogDelegate::OnDialogClosed(
    const std::string& json_retval) {
  // Get the final dialog size and store it.
  flow_handler_->StoreDialogClientSize();

  // If we're modal we can show the dialog with no browser.
  // End the keep-alive so that Chrome can exit.
  if (!modal_parent_ && keep_alive_when_non_modal_) {
    // Post to prevent recursive call tho this function.
    base::MessageLoop::current()->PostTask(
        FROM_HERE, base::Bind(&chrome::DecrementKeepAliveCount));
  }
  delete this;
}

void CloudPrintWebDialogDelegate::OnCloseContents(WebContents* source,
                                                  bool* out_close_dialog) {
  if (out_close_dialog)
    *out_close_dialog = true;
}

bool CloudPrintWebDialogDelegate::ShouldShowDialogTitle() const {
  return false;
}

bool CloudPrintWebDialogDelegate::HandleContextMenu(
    const content::ContextMenuParams& params) {
  return true;
}

// Called from the UI thread, starts up the dialog.
void CreateDialogImpl(content::BrowserContext* browser_context,
                      gfx::NativeWindow modal_parent,
                      const base::RefCountedMemory* data,
                      const base::string16& print_job_title,
                      const base::string16& print_ticket,
                      const std::string& file_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  WebDialogDelegate* dialog_delegate =
      new internal_cloud_print_helpers::CloudPrintWebDialogDelegate(
          browser_context, modal_parent, data, std::string(), print_job_title,
          print_ticket, file_type);
#if defined(OS_WIN)
  gfx::NativeWindow window =
#endif
      chrome::ShowWebDialog(modal_parent,
                            Profile::FromBrowserContext(browser_context),
                            dialog_delegate);
#if defined(OS_WIN)
  if (window) {
    HWND dialog_handle;
#if defined(USE_AURA)
    dialog_handle = window->GetHost()->GetAcceleratedWidget();
#else
    dialog_handle = window;
#endif
    if (::GetForegroundWindow() != dialog_handle) {
      ui::ForegroundHelper::SetForeground(dialog_handle);
    }
  }
#endif
}

void CreateDialogForFileImpl(content::BrowserContext* browser_context,
                             gfx::NativeWindow modal_parent,
                             const base::FilePath& path_to_file,
                             const base::string16& print_job_title,
                             const base::string16& print_ticket,
                             const std::string& file_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
  scoped_refptr<base::RefCountedMemory> data;
  int64 file_size = 0;
  if (base::GetFileSize(path_to_file, &file_size) && file_size != 0) {
    std::string file_data;
    if (file_size < kuint32max) {
      file_data.reserve(static_cast<unsigned int>(file_size));
    } else {
      DLOG(WARNING) << " print data file too large to reserve space";
    }
    if (base::ReadFileToString(path_to_file, &file_data)) {
      data = base::RefCountedString::TakeString(&file_data);
    }
  }
  // Proceed even for empty data to simplify testing.
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&print_dialog_cloud::CreatePrintDialogForBytes,
                 browser_context, modal_parent, data, print_job_title,
                 print_ticket, file_type));
  base::DeleteFile(path_to_file, false);
}

}  // namespace internal_cloud_print_helpers

namespace print_dialog_cloud {

void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterIntegerPref(
      prefs::kCloudPrintDialogWidth,
      kDefaultWidth,
      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
  registry->RegisterIntegerPref(
      prefs::kCloudPrintDialogHeight,
      kDefaultHeight,
      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}

// Called on the FILE or UI thread.  This is the main entry point into creating
// the dialog.

void CreatePrintDialogForFile(content::BrowserContext* browser_context,
                              gfx::NativeWindow modal_parent,
                              const base::FilePath& path_to_file,
                              const base::string16& print_job_title,
                              const base::string16& print_ticket,
                              const std::string& file_type) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE) ||
         BrowserThread::CurrentlyOn(BrowserThread::UI));
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      base::Bind(&internal_cloud_print_helpers::CreateDialogForFileImpl,
                 browser_context, modal_parent, path_to_file, print_job_title,
                 print_ticket, file_type));
}

void CreateCloudPrintSigninTab(Browser* browser,
                               bool add_account,
                               const base::Closure& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (switches::IsEnableAccountConsistency() &&
      !browser->profile()->IsOffTheRecord()) {
    browser->window()->ShowAvatarBubbleFromAvatarButton(
        add_account ? BrowserWindow::AVATAR_BUBBLE_MODE_ADD_ACCOUNT
                    : BrowserWindow::AVATAR_BUBBLE_MODE_SIGNIN,
        signin::ManageAccountsParams());
  } else {
    GURL url = add_account ? cloud_devices::GetCloudPrintAddAccountURL()
                           : cloud_devices::GetCloudPrintSigninURL();
    content::WebContents* web_contents =
        browser->OpenURL(content::OpenURLParams(
            google_util::AppendGoogleLocaleParam(
                url, g_browser_process->GetApplicationLocale()),
            content::Referrer(),
            NEW_FOREGROUND_TAB,
            content::PAGE_TRANSITION_AUTO_BOOKMARK,
            false));
    new SignInObserver(web_contents, cloud_devices::GetCloudPrintURL(),
                        callback);
  }
}

void CreatePrintDialogForBytes(content::BrowserContext* browser_context,
                               gfx::NativeWindow modal_parent,
                               const base::RefCountedMemory* data,
                               const base::string16& print_job_title,
                               const base::string16& print_ticket,
                               const std::string& file_type) {
  internal_cloud_print_helpers::CreateDialogImpl(browser_context, modal_parent,
                                                 data, print_job_title,
                                                 print_ticket, file_type);
}

bool CreatePrintDialogFromCommandLine(Profile* profile,
                                      const CommandLine& command_line) {
  DCHECK(command_line.HasSwitch(switches::kCloudPrintFile));
  if (!command_line.GetSwitchValuePath(switches::kCloudPrintFile).empty()) {
    base::FilePath cloud_print_file;
    cloud_print_file =
        command_line.GetSwitchValuePath(switches::kCloudPrintFile);
    if (!cloud_print_file.empty()) {
      base::string16 print_job_title;
      base::string16 print_job_print_ticket;
      if (command_line.HasSwitch(switches::kCloudPrintJobTitle)) {
        print_job_title =
          internal_cloud_print_helpers::GetSwitchValueString16(
              command_line, switches::kCloudPrintJobTitle);
      }
      if (command_line.HasSwitch(switches::kCloudPrintPrintTicket)) {
        print_job_print_ticket =
          internal_cloud_print_helpers::GetSwitchValueString16(
              command_line, switches::kCloudPrintPrintTicket);
      }
      std::string file_type = "application/pdf";
      if (command_line.HasSwitch(switches::kCloudPrintFileType)) {
        file_type = command_line.GetSwitchValueASCII(
            switches::kCloudPrintFileType);
      }

      print_dialog_cloud::CreatePrintDialogForFile(profile, NULL,
          cloud_print_file, print_job_title, print_job_print_ticket, file_type);
      return true;
    }
  }
  return false;
}

}  // namespace print_dialog_cloud
