// 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/ui/login/login_handler.h"

#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/blocked_content/popunder_preventer.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/views/login_view.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"

namespace chrome {

namespace {

// This class simply forwards the authentication from the LoginView (on
// the UI thread) to the net::URLRequest (on the I/O thread).
// This class uses ref counting to ensure that it lives until all InvokeLaters
// have been called.
class LoginHandlerViews : public LoginHandler {
 public:
  LoginHandlerViews(const net::AuthChallengeInfo& auth_info,
                    content::WebContents* web_contents,
                    LoginAuthRequiredCallback auth_required_callback)
      : LoginHandler(auth_info,
                     web_contents,
                     std::move(auth_required_callback)),
        popunder_preventer_(std::make_unique<PopunderPreventer>(web_contents)) {
    RecordDialogCreation(DialogIdentifier::LOGIN_HANDLER);
  }

  ~LoginHandlerViews() override {
    // LoginHandler cannot call CloseDialog because the subclass will already
    // have been destructed.
    CloseDialog();
  }

 protected:
  // LoginHandler:
  void BuildViewImpl(const base::string16& authority,
                     const base::string16& explanation,
                     LoginModelData* login_model_data) override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    DCHECK(!dialog_);

    dialog_ = new Dialog(this, web_contents(), authority, explanation,
                         login_model_data);
  }

  void CloseDialog() override {
    // The hosting widget may have been freed.
    if (dialog_) {
      dialog_->CloseDialog();
      dialog_ = nullptr;
    }
    popunder_preventer_ = nullptr;
  }

 private:
  void OnDialogDestroyed() { dialog_ = nullptr; }

  // The DialogDelegate is a separate object from LoginHandlerViews so it can be
  // owned by the views hierarchy (see DeleteDelegate).
  class Dialog : public views::DialogDelegate {
   public:
    // Creates a Dialog which reports the results back to |handler|. Note the
    // Dialog is responsible for its own lifetime, which may be independent of
    // |handler|. |handler| may decide to close the Dialog, by calling
    // CloseDialog, or the Dialog may have been destroyed by the views
    // hierarchy, in which case it will call handler->OnDialogDestroyed. When
    // one of these methods is called, whichever comes first, each object must
    // release pointers to the other.
    Dialog(LoginHandlerViews* handler,
           content::WebContents* web_contents,
           const base::string16& authority,
           const base::string16& explanation,
           LoginHandler::LoginModelData* login_model_data)
        : handler_(handler), login_view_(nullptr), widget_(nullptr) {
      // Create a new LoginView and set the model for it.  The model (password
      // manager) is owned by the WebContents, but the view is parented to the
      // browser window, so the view may be destroyed after the password
      // manager. The view listens for model destruction and unobserves
      // accordingly.
      login_view_ = new LoginView(authority, explanation, login_model_data);

      // ShowWebModalDialogViews takes ownership of this, by way of the
      // DeleteDelegate method.
      widget_ = constrained_window::ShowWebModalDialogViews(this, web_contents);
    }

    void CloseDialog() {
      handler_ = nullptr;
      // The hosting widget may have been freed.
      if (widget_)
        widget_->Close();
    }

    // views::DialogDelegate:
    bool ShouldShowCloseButton() const override { return false; }

    base::string16 GetDialogButtonLabel(
        ui::DialogButton button) const override {
      if (button == ui::DIALOG_BUTTON_OK)
        return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
      return DialogDelegate::GetDialogButtonLabel(button);
    }

    base::string16 GetWindowTitle() const override {
      return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_TITLE);
    }

    void WindowClosing() override {
      // Reference is no longer valid.
      widget_ = nullptr;
      if (handler_)
        handler_->CancelAuth();
    }

    void DeleteDelegate() override { delete this; }

    ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; }

    bool Cancel() override {
      DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
      if (handler_)
        handler_->CancelAuth();
      return true;
    }

    bool Accept() override {
      DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
      if (handler_)
        handler_->SetAuth(login_view_->GetUsername(),
                          login_view_->GetPassword());
      return true;
    }

    views::View* GetInitiallyFocusedView() override {
      return login_view_->GetInitiallyFocusedView();
    }

    views::View* GetContentsView() override { return login_view_; }
    views::Widget* GetWidget() override { return login_view_->GetWidget(); }
    const views::Widget* GetWidget() const override {
      return login_view_->GetWidget();
    }

   private:
    ~Dialog() override {
      if (handler_)
        handler_->OnDialogDestroyed();
    }

    LoginHandlerViews* handler_;
    // The LoginView that contains the user's login information.
    LoginView* login_view_;
    views::Widget* widget_;

    DISALLOW_COPY_AND_ASSIGN(Dialog);
  };

  Dialog* dialog_ = nullptr;
  std::unique_ptr<PopunderPreventer> popunder_preventer_;

  DISALLOW_COPY_AND_ASSIGN(LoginHandlerViews);
};

}  // namespace

std::unique_ptr<LoginHandler> CreateLoginHandlerViews(
    const net::AuthChallengeInfo& auth_info,
    content::WebContents* web_contents,
    LoginAuthRequiredCallback auth_required_callback) {
  return std::make_unique<LoginHandlerViews>(auth_info, web_contents,
                                             std::move(auth_required_callback));
}

}  // namespace chrome
