// 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 "ui/web_dialogs/web_dialog_ui.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/values.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/common/bindings_policy.h"
#include "ui/web_dialogs/web_dialog_delegate.h"

using content::RenderViewHost;
using content::WebUIMessageHandler;

namespace ui {

namespace {

const char kWebDialogDelegateUserDataKey[] = "WebDialogDelegateUserData";

class WebDialogDelegateUserData : public base::SupportsUserData::Data {
 public:
  explicit WebDialogDelegateUserData(WebDialogDelegate* delegate)
      : delegate_(delegate) {}
  ~WebDialogDelegateUserData() override {}
  WebDialogDelegate* delegate() { return delegate_; }

 private:
  WebDialogDelegate* delegate_;  // unowned
};

}  // namespace

WebDialogUI::WebDialogUI(content::WebUI* web_ui)
    : WebUIController(web_ui) {
}

WebDialogUI::~WebDialogUI() {
  // Don't unregister our user data. During the teardown of the WebContents,
  // this will be deleted, but the WebContents will already be destroyed.
  //
  // This object is owned indirectly by the WebContents. WebUIs can change, so
  // it's scary if this WebUI is changed out and replaced with something else,
  // since the user data will still point to the old delegate. But the delegate
  // is itself the owner of the WebContents for a dialog so will be in scope,
  // and the HTML dialogs won't swap WebUIs anyway since they don't navigate.
}

void WebDialogUI::CloseDialog(const base::ListValue* args) {
  OnDialogClosed(args);
}

// static
void WebDialogUI::SetDelegate(content::WebContents* web_contents,
                              WebDialogDelegate* delegate) {
  web_contents->SetUserData(&kWebDialogDelegateUserDataKey,
                            new WebDialogDelegateUserData(delegate));
}

////////////////////////////////////////////////////////////////////////////////
// Private:

WebDialogDelegate* WebDialogUI::GetDelegate(
    content::WebContents* web_contents) {
  WebDialogDelegateUserData* user_data =
      static_cast<WebDialogDelegateUserData*>(
          web_contents->GetUserData(&kWebDialogDelegateUserDataKey));

  return user_data ? user_data->delegate() : NULL;
}


void WebDialogUI::RenderViewCreated(RenderViewHost* render_view_host) {
  // Hook up the javascript function calls, also known as chrome.send("foo")
  // calls in the HTML, to the actual C++ functions.
  web_ui()->RegisterMessageCallback("dialogClose",
      base::Bind(&WebDialogUI::OnDialogClosed, base::Unretained(this)));

  // Pass the arguments to the renderer supplied by the delegate.
  std::string dialog_args;
  std::vector<WebUIMessageHandler*> handlers;
  WebDialogDelegate* delegate = GetDelegate(web_ui()->GetWebContents());
  if (delegate) {
    dialog_args = delegate->GetDialogArgs();
    delegate->GetWebUIMessageHandlers(&handlers);
  }

  if (0 != (web_ui()->GetBindings() & content::BINDINGS_POLICY_WEB_UI))
    render_view_host->SetWebUIProperty("dialogArguments", dialog_args);
  for (std::vector<WebUIMessageHandler*>::iterator it = handlers.begin();
       it != handlers.end(); ++it) {
    web_ui()->AddMessageHandler(*it);
  }

  if (delegate)
    delegate->OnDialogShown(web_ui(), render_view_host);
}

void WebDialogUI::OnDialogClosed(const base::ListValue* args) {
  WebDialogDelegate* delegate = GetDelegate(web_ui()->GetWebContents());
  if (delegate) {
    std::string json_retval;
    if (args && !args->empty() && !args->GetString(0, &json_retval))
      NOTREACHED() << "Could not read JSON argument";

    delegate->OnDialogCloseFromWebUI(json_retval);
  }
}

}  // namespace ui
