// Copyright (c) 2011 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_REMOTING_SETUP_FLOW_H_
#define CHROME_BROWSER_REMOTING_SETUP_FLOW_H_

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "chrome/common/remoting/chromoting_host_info.h"
#include "content/browser/webui/web_ui.h"

class ListValue;
class ServiceProcessControl;

namespace remoting {

class SetupFlow;

// SetupFlowStep represents a single step for SetupFlow, e.g. login or
// host registration. When a step is finished, GetNextStep() is called
// to get the step that must follow.
class SetupFlowStep {
 public:
  typedef Callback0::Type DoneCallback;

  SetupFlowStep();
  virtual ~SetupFlowStep();

  // Start the step. Ownership of |done_callback| is given to the
  // function. |done_callback| is called when the step is finished,
  // The callback must be called on the same thread as Start().
  virtual void Start(SetupFlow* flow, DoneCallback* done_callback) = 0;

  // Called to handle |message| received from UI. |args| may be set to
  // NULL.
  virtual void HandleMessage(const std::string& message, const Value* arg) = 0;

  // Called if user closes the dialog.
  virtual void Cancel() = 0;

  // Returns SetupFlowStep object that corresponds to the next
  // step. Must never return NULL.
  virtual SetupFlowStep* GetNextStep() = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(SetupFlowStep);
};

// SetupFlowStepBase implements base functions common for all
// SetupFlowStep implementations.
class SetupFlowStepBase : public SetupFlowStep {
 public:
  SetupFlowStepBase();
  ~SetupFlowStepBase();

  // SetupFlowStep implementation.
  virtual void Start(SetupFlow* flow, DoneCallback* done_callback);
  virtual SetupFlowStep* GetNextStep();

 protected:
  SetupFlow* flow() { return flow_; }

  void ExecuteJavascriptInIFrame(const std::wstring& iframe_xpath,
                                 const std::wstring& js);

  // Finish current step. Calls |done_callback| specified in Start().
  // GetNextStep() will return the specified |next_step|.
  void FinishStep(SetupFlowStep* next_step);

  // Called from Start(). Child classes must override this method
  // instead of Start().
  virtual void DoStart() = 0;

 private:
  SetupFlow* flow_;
  scoped_ptr<DoneCallback> done_callback_;
  bool done_;

  // Next step stored between Done() and GetNextStep();
  SetupFlowStep* next_step_;

  DISALLOW_COPY_AND_ASSIGN(SetupFlowStepBase);
};

// Base class for error steps. It shows the error message returned by
// GetErrorMessage() and Retry button.
class SetupFlowErrorStepBase : public SetupFlowStepBase {
 public:
  SetupFlowErrorStepBase();
  virtual ~SetupFlowErrorStepBase();

  // SetupFlowStep implementation.
  virtual void HandleMessage(const std::string& message, const Value* arg);
  virtual void Cancel();

 protected:
  virtual void DoStart();

  // Returns error message that is shown to the user.
  virtual string16 GetErrorMessage() = 0;

  // Called when user clicks Retry button. Normally this methoud just
  // calls FinishStep() with an appropriate next step.
  virtual void Retry() = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(SetupFlowErrorStepBase);
};

// The last step in the setup flow. This step never finishes, user is
// expected to close dialog after that.
class SetupFlowDoneStep : public SetupFlowStepBase {
 public:
  SetupFlowDoneStep();
  explicit SetupFlowDoneStep(const string16& message);
  virtual ~SetupFlowDoneStep();

  // SetupFlowStep implementation.
  virtual void HandleMessage(const std::string& message, const Value* arg);
  virtual void Cancel();

 protected:
  virtual void DoStart();

 private:
  string16 message_;

  DISALLOW_COPY_AND_ASSIGN(SetupFlowDoneStep);
};

// SetupFlowContext stores data that needs to be passed between
// different setup flow steps.
struct SetupFlowContext {
  SetupFlowContext();
  ~SetupFlowContext();

  std::string login;
  std::string remoting_token;
  std::string talk_token;

  ChromotingHostInfo host_info;
};

// This class is responsible for showing a remoting setup dialog and
// perform operations to fill the content of the dialog and handle
// user actions in the dialog.
//
// Each page in the setup flow may send message to the current
// step. In order to do that it must use send a RemotingSetup message
// and specify message name as the first value in the argument
// list. For example the following code sends Retry message to the
// current step:
//
//     chrome.send("RemotingSetup", ["Retry"])
//
// Assitional message parameters may be provided via send value in the
// arguments list, e.g.:
//
//     chrome.send("RemotingSetup", ["SubmitAuth", auth_data])
//
// In this case auth_data would be passed in
// SetupFlowStep::HandleMessage().
class SetupFlow : public WebUIMessageHandler,
                  public HtmlDialogUIDelegate {
 public:
  virtual ~SetupFlow();

  static SetupFlow* OpenSetupDialog(Profile* profile);

  WebUI* web_ui() { return web_ui_; }
  Profile* profile() { return profile_; }
  SetupFlowContext* context() { return &context_; }

 private:
  explicit SetupFlow(const std::string& args, Profile* profile,
                     SetupFlowStep* first_step);

  // HtmlDialogUIDelegate implementation.
  virtual GURL GetDialogContentURL() const;
  virtual void GetWebUIMessageHandlers(
      std::vector<WebUIMessageHandler*>* handlers) const;
  virtual void GetDialogSize(gfx::Size* size) const;
  virtual std::string GetDialogArgs() const;
  virtual void OnDialogClosed(const std::string& json_retval);
  virtual void OnCloseContents(TabContents* source, bool* out_close_dialog);
  virtual std::wstring GetDialogTitle() const;
  virtual bool IsDialogModal() const;
  virtual bool ShouldShowDialogTitle() const;

  // WebUIMessageHandler implementation.
  virtual WebUIMessageHandler* Attach(WebUI* web_ui);
  virtual void RegisterMessages();

  // Message handlers for the messages we receive from UI.
  void HandleSubmitAuth(const ListValue* args);
  void HandleUIMessage(const ListValue* args);

  void StartCurrentStep();
  void OnStepDone();

  // Pointer to the Web UI. This is provided by RemotingSetupMessageHandler
  // when attached.
  WebUI* web_ui_;

  // The args to pass to the initial page.
  std::string dialog_start_args_;
  Profile* profile_;

  SetupFlowContext context_;

  scoped_ptr<SetupFlowStep> current_step_;

  DISALLOW_COPY_AND_ASSIGN(SetupFlow);
};

}  // namespace remoting

#endif  // CHROME_BROWSER_REMOTING_SETUP_FLOW_H_
