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

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/crypto_module_blocking_password_delegate.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace chrome {

namespace {

class CryptoModuleBlockingDialogDelegate
    : public crypto::CryptoModuleBlockingPasswordDelegate {
 public:
  CryptoModuleBlockingDialogDelegate(CryptoModulePasswordReason reason,
                                     const std::string& server)
      : event_(false, false),
        reason_(reason),
        server_(server),
        cancelled_(false) {
  }

  virtual ~CryptoModuleBlockingDialogDelegate() {
    // Make sure we clear the password in memory.
    password_.replace(0, password_.size(), password_.size(), 0);
  }

  // crypto::CryptoModuleBlockingDialogDelegate implementation.
  virtual std::string RequestPassword(const std::string& slot_name,
                                      bool retry,
                                      bool* cancelled) OVERRIDE {
    DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
    DCHECK(!event_.IsSignaled());
    event_.Reset();

    if (BrowserThread::PostTask(
            BrowserThread::UI, FROM_HERE,
            base::Bind(&CryptoModuleBlockingDialogDelegate::ShowDialog,
                       // We block on event_ until the task completes, so
                       // there's no need to ref-count.
                       base::Unretained(this),
                       slot_name,
                       retry))) {
      event_.Wait();
    }
    *cancelled = cancelled_;
    return password_;
  }

 private:
  void ShowDialog(const std::string& slot_name,
                  bool retry) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    ShowCryptoModulePasswordDialog(
        slot_name, retry, reason_, server_,
        base::Bind(&CryptoModuleBlockingDialogDelegate::GotPassword,
                   // We block on event_ until the task completes, so
                   // there's no need to ref-count.
                   base::Unretained(this)));
  }

  void GotPassword(const char* password) {
    if (password)
      password_ = password;
    else
      cancelled_ = true;
    event_.Signal();
  }

  base::WaitableEvent event_;
  CryptoModulePasswordReason reason_;
  std::string server_;
  std::string password_;
  bool cancelled_;

  DISALLOW_COPY_AND_ASSIGN(CryptoModuleBlockingDialogDelegate);
};

}  // namespace

crypto::CryptoModuleBlockingPasswordDelegate*
    NewCryptoModuleBlockingDialogDelegate(CryptoModulePasswordReason reason,
                                          const std::string& server) {
  return new CryptoModuleBlockingDialogDelegate(reason, server);
}

}  // namespace chrome
