// 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/chromeos/options/vpn_config_view.h"

#include "ash/system/chromeos/network/network_connect.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/enrollment_dialog_view.h"
#include "chrome/browser/chromeos/net/onc_utils.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/net/x509_certificate_model.h"
#include "chromeos/network/network_configuration_handler.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_ui_data.h"
#include "chromeos/network/onc/onc_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/base/events/event.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_client_view.h"

namespace {

// Root CA certificates that are built into Chrome use this token name.
const char* const kRootCertificateTokenName = "Builtin Object Token";

enum ProviderTypeIndex {
  PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK = 0,
  PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT = 1,
  PROVIDER_TYPE_INDEX_OPEN_VPN = 2,
  PROVIDER_TYPE_INDEX_MAX = 3,
};

string16 ProviderTypeIndexToString(int index) {
  switch (index) {
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK:
      return l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK);
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT:
      return l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT);
    case PROVIDER_TYPE_INDEX_OPEN_VPN:
      return l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN);
  }
  NOTREACHED();
  return string16();
}

int ProviderTypeToIndex(const std::string& provider_type,
                        const std::string& client_cert_id) {
  if (provider_type == flimflam::kProviderL2tpIpsec) {
    if (!client_cert_id.empty())
      return PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT;
    else
      return PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK;
  } else {
    DCHECK(provider_type == flimflam::kProviderOpenVpn);
    return PROVIDER_TYPE_INDEX_OPEN_VPN;
  }
}

// Translates the provider type to the name of the respective ONC dictionary
// containing configuration data for the type.
std::string ProviderTypeIndexToONCDictKey(int provider_type_index) {
  switch (provider_type_index) {
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK:
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT:
      return chromeos::onc::vpn::kIPsec;
    case PROVIDER_TYPE_INDEX_OPEN_VPN:
      return chromeos::onc::vpn::kOpenVPN;
  }
  NOTREACHED() << "Unhandled provider type index " << provider_type_index;
  return std::string();
}

std::string GetPemFromDictionary(
    const base::DictionaryValue* provider_properties,
    const std::string& key) {
  const base::ListValue* pems = NULL;
  if (!provider_properties->GetListWithoutPathExpansion(key, &pems))
    return std::string();
  std::string pem;
  pems->GetString(0, &pem);
  return pem;
}

void ShillError(const std::string& function,
                const std::string& error_name,
                scoped_ptr<base::DictionaryValue> error_data) {
  NET_LOG_ERROR("Shill Error from VpnConfigView: " + error_name, function);
}

}  // namespace

namespace chromeos {

namespace internal {

class ProviderTypeComboboxModel : public ui::ComboboxModel {
 public:
  ProviderTypeComboboxModel();
  virtual ~ProviderTypeComboboxModel();

  // Overridden from ui::ComboboxModel:
  virtual int GetItemCount() const OVERRIDE;
  virtual string16 GetItemAt(int index) OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(ProviderTypeComboboxModel);
};

class VpnServerCACertComboboxModel : public ui::ComboboxModel {
 public:
  VpnServerCACertComboboxModel();
  virtual ~VpnServerCACertComboboxModel();

  // Overridden from ui::ComboboxModel:
  virtual int GetItemCount() const OVERRIDE;
  virtual string16 GetItemAt(int index) OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(VpnServerCACertComboboxModel);
};

class VpnUserCertComboboxModel : public ui::ComboboxModel {
 public:
  VpnUserCertComboboxModel();
  virtual ~VpnUserCertComboboxModel();

  // Overridden from ui::ComboboxModel:
  virtual int GetItemCount() const OVERRIDE;
  virtual string16 GetItemAt(int index) OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(VpnUserCertComboboxModel);
};

// ProviderTypeComboboxModel ---------------------------------------------------

ProviderTypeComboboxModel::ProviderTypeComboboxModel() {
}

ProviderTypeComboboxModel::~ProviderTypeComboboxModel() {
}

int ProviderTypeComboboxModel::GetItemCount() const {
  return PROVIDER_TYPE_INDEX_MAX;
}

string16 ProviderTypeComboboxModel::GetItemAt(int index) {
  return ProviderTypeIndexToString(index);
}

// VpnServerCACertComboboxModel ------------------------------------------------

VpnServerCACertComboboxModel::VpnServerCACertComboboxModel() {
}

VpnServerCACertComboboxModel::~VpnServerCACertComboboxModel() {
}

int VpnServerCACertComboboxModel::GetItemCount() const {
  if (CertLibrary::Get()->CertificatesLoading())
    return 1;  // "Loading"
  // "Default" + certs.
  return CertLibrary::Get()->NumCertificates(
      CertLibrary::CERT_TYPE_SERVER_CA) + 1;
}

string16 VpnServerCACertComboboxModel::GetItemAt(int index) {
  if (CertLibrary::Get()->CertificatesLoading())
    return l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
  if (index == 0)
    return l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
  int cert_index = index - 1;
  return CertLibrary::Get()->GetCertDisplayStringAt(
      CertLibrary::CERT_TYPE_SERVER_CA, cert_index);
}

// VpnUserCertComboboxModel ----------------------------------------------------

VpnUserCertComboboxModel::VpnUserCertComboboxModel() {
}

VpnUserCertComboboxModel::~VpnUserCertComboboxModel() {
}

int VpnUserCertComboboxModel::GetItemCount() const {
  if (CertLibrary::Get()->CertificatesLoading())
    return 1;  // "Loading"
  int num_certs =
      CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER);
  if (num_certs == 0)
    return 1;  // "None installed"
  return num_certs;
}

string16 VpnUserCertComboboxModel::GetItemAt(int index) {
  if (CertLibrary::Get()->CertificatesLoading()) {
    return l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
  }
  if (CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) == 0) {
    return l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
  }
  return CertLibrary::Get()->GetCertDisplayStringAt(
      CertLibrary::CERT_TYPE_USER, index);
}

}  // namespace internal

VPNConfigView::VPNConfigView(NetworkConfigView* parent,
                             const std::string& service_path)
    : ChildNetworkConfigView(parent, service_path),
      service_text_modified_(false),
      enable_psk_passphrase_(false),
      enable_user_cert_(false),
      enable_server_ca_cert_(false),
      enable_otp_(false),
      enable_group_name_(false),
      title_(0),
      layout_(NULL),
      server_textfield_(NULL),
      service_text_(NULL),
      service_textfield_(NULL),
      provider_type_combobox_(NULL),
      provider_type_text_label_(NULL),
      psk_passphrase_label_(NULL),
      psk_passphrase_textfield_(NULL),
      user_cert_label_(NULL),
      user_cert_combobox_(NULL),
      server_ca_cert_label_(NULL),
      server_ca_cert_combobox_(NULL),
      username_textfield_(NULL),
      user_passphrase_textfield_(NULL),
      otp_label_(NULL),
      otp_textfield_(NULL),
      group_name_label_(NULL),
      group_name_textfield_(NULL),
      save_credentials_checkbox_(NULL),
      error_label_(NULL),
      provider_type_index_(PROVIDER_TYPE_INDEX_MAX),
      weak_ptr_factory_(this) {
  Init();
}

VPNConfigView::~VPNConfigView() {
  CertLibrary::Get()->RemoveObserver(this);
}

string16 VPNConfigView::GetTitle() const {
  DCHECK_NE(title_, 0);
  return l10n_util::GetStringUTF16(title_);
}

views::View* VPNConfigView::GetInitiallyFocusedView() {
  if (service_path_.empty()) {
    // Put focus in the first editable field.
    if (server_textfield_)
      return server_textfield_;
    else if (service_textfield_)
      return service_textfield_;
    else if (provider_type_combobox_)
      return provider_type_combobox_;
    else if (psk_passphrase_textfield_ && psk_passphrase_textfield_->enabled())
      return psk_passphrase_textfield_;
    else if (user_cert_combobox_ && user_cert_combobox_->enabled())
      return user_cert_combobox_;
    else if (server_ca_cert_combobox_ && server_ca_cert_combobox_->enabled())
      return server_ca_cert_combobox_;
  }
  if (user_passphrase_textfield_)
    return user_passphrase_textfield_;
  else if (otp_textfield_)
    return otp_textfield_;
  return NULL;
}

bool VPNConfigView::CanLogin() {
  // Username is always required.
  if (GetUsername().empty())
    return false;

  // TODO(stevenjb): min kMinPassphraseLen length?
  if (service_path_.empty() &&
      (GetService().empty() || GetServer().empty()))
    return false;

  // Block login if certs are required but user has none.
  bool cert_required =
      GetProviderTypeIndex() == PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT;
  if (cert_required && (!HaveUserCerts() || !IsUserCertValid()))
    return false;

  return true;
}

void VPNConfigView::ContentsChanged(views::Textfield* sender,
                                    const string16& new_contents) {
  if (sender == server_textfield_ && !service_text_modified_) {
    // Set the service name to the server name up to '.', unless it has
    // been explicitly set by the user.
    string16 server = server_textfield_->text();
    string16::size_type n = server.find_first_of(L'.');
    service_name_from_server_ = server.substr(0, n);
    service_textfield_->SetText(service_name_from_server_);
  }
  if (sender == service_textfield_) {
    if (new_contents.empty())
      service_text_modified_ = false;
    else if (new_contents != service_name_from_server_)
      service_text_modified_ = true;
  }
  UpdateCanLogin();
}

bool VPNConfigView::HandleKeyEvent(views::Textfield* sender,
                                   const ui::KeyEvent& key_event) {
  if ((sender == psk_passphrase_textfield_ ||
       sender == user_passphrase_textfield_) &&
      key_event.key_code() == ui::VKEY_RETURN) {
    parent_->GetDialogClientView()->AcceptWindow();
  }
  return false;
}

void VPNConfigView::ButtonPressed(views::Button* sender,
                                  const ui::Event& event) {
}

void VPNConfigView::OnSelectedIndexChanged(views::Combobox* combobox) {
  UpdateControls();
  UpdateErrorLabel();
  UpdateCanLogin();
}

void VPNConfigView::OnCertificatesLoaded(bool initial_load) {
  Refresh();
}

bool VPNConfigView::Login() {
  if (service_path_.empty()) {
    base::DictionaryValue properties;
    // Identifying properties
    properties.SetStringWithoutPathExpansion(
        flimflam::kTypeProperty, flimflam::kTypeVPN);
    properties.SetStringWithoutPathExpansion(
        flimflam::kNameProperty, GetService());
    properties.SetStringWithoutPathExpansion(
        flimflam::kProviderHostProperty, GetServer());
    properties.SetStringWithoutPathExpansion(
        flimflam::kProviderTypeProperty, GetProviderTypeString());

    SetConfigProperties(&properties);
    ash::network_connect::CreateConfigurationAndConnect(
        &properties, false /* not shared */);
  } else {
    const NetworkState* vpn = NetworkHandler::Get()->network_state_handler()->
        GetNetworkState(service_path_);
    if (!vpn) {
      // Shill no longer knows about this network (edge case).
      // TODO(stevenjb): Add notification for this.
      NET_LOG_ERROR("Network not found", service_path_);
      return true;  // Close dialog
    }
    base::DictionaryValue properties;
    SetConfigProperties(&properties);
    ash::network_connect::ConfigureNetworkAndConnect(
        service_path_, properties, false /* not shared */);
  }
  return true;  // Close dialog.
}

void VPNConfigView::Cancel() {
}

void VPNConfigView::InitFocus() {
  views::View* view_to_focus = GetInitiallyFocusedView();
  if (view_to_focus)
    view_to_focus->RequestFocus();
}

const std::string VPNConfigView::GetService() const {
  if (service_textfield_ != NULL)
    return GetTextFromField(service_textfield_, true);
  return service_path_;
}

const std::string VPNConfigView::GetServer() const {
  if (server_textfield_ != NULL)
    return GetTextFromField(server_textfield_, true);
  return std::string();
}

const std::string VPNConfigView::GetPSKPassphrase() const {
  if (psk_passphrase_textfield_ &&
      enable_psk_passphrase_ &&
      psk_passphrase_textfield_->visible())
    return GetPassphraseFromField(psk_passphrase_textfield_);
  return std::string();
}

const std::string VPNConfigView::GetUsername() const {
  return GetTextFromField(username_textfield_, true);
}

const std::string VPNConfigView::GetUserPassphrase() const {
  return GetPassphraseFromField(user_passphrase_textfield_);
}

const std::string VPNConfigView::GetGroupName() const {
  return GetTextFromField(group_name_textfield_, false);
}

const std::string VPNConfigView::GetOTP() const {
  return GetTextFromField(otp_textfield_, true);
}

const std::string VPNConfigView::GetServerCACertPEM() const {
  int index = server_ca_cert_combobox_ ?
      server_ca_cert_combobox_->selected_index() : 0;
  if (index == 0) {
    // First item is "Default".
    return std::string();
  } else {
    int cert_index = index - 1;
    return CertLibrary::Get()->GetCertPEMAt(
        CertLibrary::CERT_TYPE_SERVER_CA, cert_index);
  }
}

const std::string VPNConfigView::GetUserCertID() const {
  if (!HaveUserCerts()) {
    return std::string();  // "None installed"
  } else {
    // Certificates are listed in the order they appear in the model.
    int index = user_cert_combobox_ ? user_cert_combobox_->selected_index() : 0;
    return CertLibrary::Get()->GetCertPkcs11IdAt(
        CertLibrary::CERT_TYPE_USER, index);
  }
}

bool VPNConfigView::GetSaveCredentials() const {
  return save_credentials_checkbox_->checked();
}

int VPNConfigView::GetProviderTypeIndex() const {
  if (provider_type_combobox_)
    return provider_type_combobox_->selected_index();
  return provider_type_index_;
}

std::string VPNConfigView::GetProviderTypeString() const {
  int index = GetProviderTypeIndex();
  switch (index) {
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK:
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT:
      return flimflam::kProviderL2tpIpsec;
    case PROVIDER_TYPE_INDEX_OPEN_VPN:
      return flimflam::kProviderOpenVpn;
  }
  NOTREACHED();
  return std::string();
}

void VPNConfigView::Init() {
  const NetworkState* vpn = NULL;
  if (!service_path_.empty()) {
    vpn = NetworkHandler::Get()->network_state_handler()->
        GetNetworkState(service_path_);
    DCHECK(vpn && vpn->type() == flimflam::kTypeVPN);
  }
  layout_ = views::GridLayout::CreatePanel(this);
  SetLayoutManager(layout_);

  // Observer any changes to the certificate list.
  CertLibrary::Get()->AddObserver(this);

  views::ColumnSet* column_set = layout_->AddColumnSet(0);
  // Label.
  column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                        views::GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
  // Textfield, combobox.
  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                        views::GridLayout::USE_PREF, 0,
                        ChildNetworkConfigView::kInputFieldMinWidth);
  column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
  // Policy indicator.
  column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, 0,
                        views::GridLayout::USE_PREF, 0, 0);

  // Initialize members.
  service_text_modified_ = false;
  title_ = vpn ? IDS_OPTIONS_SETTINGS_JOIN_VPN : IDS_OPTIONS_SETTINGS_ADD_VPN;

  // By default enable all controls.
  enable_psk_passphrase_ = true;
  enable_user_cert_ = true;
  enable_server_ca_cert_ = true;
  enable_otp_ = true;
  enable_group_name_ = true;

  // Server label and input.
  layout_->StartRow(0, 0);
  views::View* server_label =
      new views::Label(l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVER_HOSTNAME));
  layout_->AddView(server_label);
  server_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
  server_textfield_->SetController(this);
  layout_->AddView(server_textfield_);
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
  if (!service_path_.empty()) {
    server_label->SetEnabled(false);
    server_textfield_->SetEnabled(false);
  }

  // Service label and name or input.
  layout_->StartRow(0, 0);
  layout_->AddView(new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVICE_NAME)));
  if (service_path_.empty()) {
    service_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
    service_textfield_->SetController(this);
    layout_->AddView(service_textfield_);
    service_text_ = NULL;
  } else {
    service_text_ = new views::Label();
    service_text_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    layout_->AddView(service_text_);
    service_textfield_ = NULL;
  }
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // Provider type label and select.
  layout_->StartRow(0, 0);
  layout_->AddView(new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_TYPE)));
  if (service_path_.empty()) {
    provider_type_combobox_model_.reset(
        new internal::ProviderTypeComboboxModel);
    provider_type_combobox_ = new views::Combobox(
        provider_type_combobox_model_.get());
    provider_type_combobox_->set_listener(this);
    layout_->AddView(provider_type_combobox_);
    provider_type_text_label_ = NULL;
  } else {
    provider_type_text_label_ = new views::Label();
    provider_type_text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    layout_->AddView(provider_type_text_label_);
    provider_type_combobox_ = NULL;
  }
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // PSK passphrase label, input and visible button.
  layout_->StartRow(0, 0);
  psk_passphrase_label_ =  new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PSK_PASSPHRASE));
  layout_->AddView(psk_passphrase_label_);
  psk_passphrase_textfield_ = new PassphraseTextfield();
  psk_passphrase_textfield_->SetController(this);
  layout_->AddView(psk_passphrase_textfield_);
  layout_->AddView(
      new ControlledSettingIndicatorView(psk_passphrase_ui_data_));
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // Server CA certificate
  if (service_path_.empty()) {
    layout_->StartRow(0, 0);
    server_ca_cert_label_ = new views::Label(l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA));
    layout_->AddView(server_ca_cert_label_);
    server_ca_cert_combobox_model_.reset(
        new internal::VpnServerCACertComboboxModel());
    server_ca_cert_combobox_ = new views::Combobox(
        server_ca_cert_combobox_model_.get());
    layout_->AddView(server_ca_cert_combobox_);
    layout_->AddView(new ControlledSettingIndicatorView(ca_cert_ui_data_));
    layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
  } else {
    server_ca_cert_label_ = NULL;
    server_ca_cert_combobox_ = NULL;
  }

  // User certificate label and input.
  layout_->StartRow(0, 0);
  user_cert_label_ = new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_CERT));
  layout_->AddView(user_cert_label_);
  user_cert_combobox_model_.reset(
      new internal::VpnUserCertComboboxModel());
  user_cert_combobox_ = new views::Combobox(user_cert_combobox_model_.get());
  user_cert_combobox_->set_listener(this);
  layout_->AddView(user_cert_combobox_);
  layout_->AddView(new ControlledSettingIndicatorView(user_cert_ui_data_));
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // Username label and input.
  layout_->StartRow(0, 0);
  layout_->AddView(new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USERNAME)));
  username_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
  username_textfield_->SetController(this);
  username_textfield_->SetEnabled(username_ui_data_.IsEditable());
  layout_->AddView(username_textfield_);
  layout_->AddView(new ControlledSettingIndicatorView(username_ui_data_));
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // User passphrase label, input and visble button.
  layout_->StartRow(0, 0);
  layout_->AddView(new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_PASSPHRASE)));
  user_passphrase_textfield_ = new PassphraseTextfield();
  user_passphrase_textfield_->SetController(this);
  user_passphrase_textfield_->SetEnabled(user_passphrase_ui_data_.IsEditable());
  layout_->AddView(user_passphrase_textfield_);
  layout_->AddView(
      new ControlledSettingIndicatorView(user_passphrase_ui_data_));
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // OTP label and input.
  layout_->StartRow(0, 0);
  otp_label_ = new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_OTP));
  layout_->AddView(otp_label_);
  otp_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
  otp_textfield_->SetController(this);
  layout_->AddView(otp_textfield_);
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // Group Name label and input.
  layout_->StartRow(0, 0);
  group_name_label_ = new views::Label(l10n_util::GetStringUTF16(
      IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_GROUP_NAME));
  layout_->AddView(group_name_label_);
  group_name_textfield_ =
      new views::Textfield(views::Textfield::STYLE_DEFAULT);
  group_name_textfield_->SetController(this);
  layout_->AddView(group_name_textfield_);
  layout_->AddView(new ControlledSettingIndicatorView(group_name_ui_data_));
  layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);

  // Save credentials
  layout_->StartRow(0, 0);
  save_credentials_checkbox_ = new views::Checkbox(
      l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS));
  save_credentials_checkbox_->SetEnabled(
      save_credentials_ui_data_.IsEditable());
  layout_->SkipColumns(1);
  layout_->AddView(save_credentials_checkbox_);
  layout_->AddView(
      new ControlledSettingIndicatorView(save_credentials_ui_data_));

  // Error label.
  layout_->StartRow(0, 0);
  layout_->SkipColumns(1);
  error_label_ = new views::Label();
  error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  error_label_->SetEnabledColor(SK_ColorRED);
  layout_->AddView(error_label_);

  // Set or hide the UI, update comboboxes and error labels.
  Refresh();

  if (vpn) {
    NetworkHandler::Get()->network_configuration_handler()->GetProperties(
        service_path_,
        base::Bind(&VPNConfigView::InitFromProperties,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&VPNConfigView::GetPropertiesError,
                   weak_ptr_factory_.GetWeakPtr()));
  }
}

void VPNConfigView::InitFromProperties(
    const std::string& service_path,
    const base::DictionaryValue& service_properties) {
  const NetworkState* vpn = NetworkHandler::Get()->network_state_handler()->
      GetNetworkState(service_path);
  if (!vpn) {
    NET_LOG_ERROR("Shill Error getting properties VpnConfigView", service_path);
    return;
  }

  std::string provider_type, server_hostname, username, group_name;
  bool psk_passphrase_required = false;
  const base::DictionaryValue* provider_properties;
  if (service_properties.GetDictionaryWithoutPathExpansion(
          flimflam::kProviderProperty, &provider_properties)) {
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kTypeProperty, &provider_type);
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kHostProperty, &server_hostname);
  }
  if (provider_type == flimflam::kProviderL2tpIpsec) {
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kL2tpIpsecClientCertIdProperty, &client_cert_id_);
    ca_cert_pem_ = GetPemFromDictionary(
        provider_properties, shill::kL2tpIpsecCaCertPemProperty);
    provider_properties->GetBooleanWithoutPathExpansion(
        flimflam::kL2tpIpsecPskRequiredProperty, &psk_passphrase_required);
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kL2tpIpsecUserProperty, &username);
    provider_properties->GetStringWithoutPathExpansion(
        shill::kL2tpIpsecTunnelGroupProperty, &group_name);
  } else if (provider_type == flimflam::kProviderOpenVpn) {
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kOpenVPNClientCertIdProperty, &client_cert_id_);
    ca_cert_pem_ = GetPemFromDictionary(
        provider_properties, shill::kOpenVPNCaCertPemProperty);
    provider_properties->GetStringWithoutPathExpansion(
        flimflam::kOpenVPNUserProperty, &username);
  }
  bool save_credentials = false;
  service_properties.GetBooleanWithoutPathExpansion(
      flimflam::kSaveCredentialsProperty, &save_credentials);

  provider_type_index_ = ProviderTypeToIndex(provider_type, client_cert_id_);

  if (service_text_)
    service_text_->SetText(ASCIIToUTF16(vpn->name()));
  if (provider_type_text_label_)
    provider_type_text_label_->SetText(
        ProviderTypeIndexToString(provider_type_index_));

  if (server_textfield_ && !server_hostname.empty())
    server_textfield_->SetText(UTF8ToUTF16(server_hostname));
  if (username_textfield_ && !username.empty())
    username_textfield_->SetText(UTF8ToUTF16(username));
  if (group_name_textfield_ && !group_name.empty())
    group_name_textfield_->SetText(UTF8ToUTF16(group_name));
  if (psk_passphrase_textfield_)
    psk_passphrase_textfield_->SetShowFake(!psk_passphrase_required);
  if (save_credentials_checkbox_)
    save_credentials_checkbox_->SetChecked(save_credentials);

  Refresh();
}

void VPNConfigView::ParseUIProperties(const NetworkState* vpn) {
  std::string type_dict_name =
      ProviderTypeIndexToONCDictKey(provider_type_index_);
  if (provider_type_index_ == PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK) {
    ParseVPNUIProperty(vpn, type_dict_name, onc::ipsec::kServerCARef,
                       &ca_cert_ui_data_);
    ParseVPNUIProperty(vpn, type_dict_name, onc::ipsec::kPSK,
                       &psk_passphrase_ui_data_);
    ParseVPNUIProperty(vpn, type_dict_name, onc::ipsec::kGroup,
                       &group_name_ui_data_);
  } else if (provider_type_index_ == PROVIDER_TYPE_INDEX_OPEN_VPN) {
    ParseVPNUIProperty(vpn, type_dict_name, onc::openvpn::kServerCARef,
                       &ca_cert_ui_data_);
  }
  ParseVPNUIProperty(vpn, type_dict_name, onc::vpn::kClientCertRef,
                     &user_cert_ui_data_);

  const std::string credentials_dict_name(
      provider_type_index_ == PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK ?
      onc::vpn::kL2TP : type_dict_name);
  ParseVPNUIProperty(vpn, credentials_dict_name, onc::vpn::kUsername,
                     &username_ui_data_);
  ParseVPNUIProperty(vpn, credentials_dict_name, onc::vpn::kPassword,
                     &user_passphrase_ui_data_);
  ParseVPNUIProperty(vpn, credentials_dict_name, onc::vpn::kSaveCredentials,
                     &save_credentials_ui_data_);
}

void VPNConfigView::GetPropertiesError(
    const std::string& error_name,
    scoped_ptr<base::DictionaryValue> error_data) {
  NET_LOG_ERROR("Shill Error from VpnConfigView: " + error_name, "");
}

void VPNConfigView::SetConfigProperties(
    base::DictionaryValue* properties) {
  int provider_type_index = GetProviderTypeIndex();
  std::string user_passphrase = GetUserPassphrase();
  std::string user_name = GetUsername();
  std::string group_name = GetGroupName();
  switch (provider_type_index) {
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK: {
      std::string psk_passphrase = GetPSKPassphrase();
      if (!psk_passphrase.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kL2tpIpsecPskProperty, GetPSKPassphrase());
      }
      if (!group_name.empty()) {
        properties->SetStringWithoutPathExpansion(
            shill::kL2tpIpsecTunnelGroupProperty, group_name);
      }
      if (!user_name.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kL2tpIpsecUserProperty, user_name);
      }
      if (!user_passphrase.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kL2tpIpsecPasswordProperty, user_passphrase);
      }
      break;
    }
    case PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT: {
      std::string ca_cert_pem = GetServerCACertPEM();
      if (!ca_cert_pem.empty()) {
        base::ListValue* pem_list = new base::ListValue;
        pem_list->AppendString(ca_cert_pem);
        properties->SetWithoutPathExpansion(
            shill::kL2tpIpsecCaCertPemProperty, pem_list);
      }
      properties->SetStringWithoutPathExpansion(
          flimflam::kL2tpIpsecClientCertIdProperty, GetUserCertID());
      if (!group_name.empty()) {
        properties->SetStringWithoutPathExpansion(
            shill::kL2tpIpsecTunnelGroupProperty, GetGroupName());
      }
      if (!user_name.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kL2tpIpsecUserProperty, user_name);
      }
      if (!user_passphrase.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kL2tpIpsecPasswordProperty, user_passphrase);
      }
      break;
    }
    case PROVIDER_TYPE_INDEX_OPEN_VPN: {
      std::string ca_cert_pem = GetServerCACertPEM();
      if (!ca_cert_pem.empty()) {
        base::ListValue* pem_list = new base::ListValue;
        pem_list->AppendString(ca_cert_pem);
        properties->SetWithoutPathExpansion(
            shill::kOpenVPNCaCertPemProperty, pem_list);
      }
      properties->SetStringWithoutPathExpansion(
          flimflam::kOpenVPNClientCertIdProperty, GetUserCertID());
      properties->SetStringWithoutPathExpansion(
          flimflam::kOpenVPNUserProperty, GetUsername());
      if (!user_passphrase.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kOpenVPNPasswordProperty, user_passphrase);
      }
      std::string otp = GetOTP();
      if (!otp.empty()) {
        properties->SetStringWithoutPathExpansion(
            flimflam::kOpenVPNOTPProperty, otp);
      }
      break;
    }
    case PROVIDER_TYPE_INDEX_MAX:
      NOTREACHED();
      break;
  }
  properties->SetBooleanWithoutPathExpansion(
      flimflam::kSaveCredentialsProperty, GetSaveCredentials());
}

void VPNConfigView::Refresh() {
  UpdateControls();

  // Set certificate combo boxes.
  if (server_ca_cert_combobox_) {
    server_ca_cert_combobox_->ModelChanged();
    if (enable_server_ca_cert_ && !ca_cert_pem_.empty()) {
      // Select the current server CA certificate in the combobox.
      int cert_index = CertLibrary::Get()->GetCertIndexByPEM(
          CertLibrary::CERT_TYPE_SERVER_CA, ca_cert_pem_);
      if (cert_index >= 0) {
        // Skip item for "Default"
        server_ca_cert_combobox_->SetSelectedIndex(1 + cert_index);
      } else {
        server_ca_cert_combobox_->SetSelectedIndex(0);
      }
    } else {
      server_ca_cert_combobox_->SetSelectedIndex(0);
    }
  }

  if (user_cert_combobox_) {
    user_cert_combobox_->ModelChanged();
    if (enable_user_cert_ && !client_cert_id_.empty()) {
      int cert_index = CertLibrary::Get()->GetCertIndexByPkcs11Id(
          CertLibrary::CERT_TYPE_USER, client_cert_id_);
      if (cert_index >= 0)
        user_cert_combobox_->SetSelectedIndex(cert_index);
      else
        user_cert_combobox_->SetSelectedIndex(0);
    } else {
      user_cert_combobox_->SetSelectedIndex(0);
    }
  }

  UpdateErrorLabel();
}

void VPNConfigView::UpdateControlsToEnable() {
  enable_psk_passphrase_ = false;
  enable_user_cert_ = false;
  enable_server_ca_cert_ = false;
  enable_otp_ = false;
  enable_group_name_ = false;
  int provider_type_index = GetProviderTypeIndex();
  if (provider_type_index == PROVIDER_TYPE_INDEX_L2TP_IPSEC_PSK) {
    enable_psk_passphrase_ = true;
    enable_group_name_ = true;
  } else if (provider_type_index == PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT) {
    enable_server_ca_cert_ = true;
    enable_user_cert_ = HaveUserCerts();
    enable_group_name_ = true;
  } else {  // PROVIDER_TYPE_INDEX_OPEN_VPN (default)
    enable_server_ca_cert_ = true;
    enable_user_cert_ = HaveUserCerts();
    enable_otp_ = true;
  }
}

void VPNConfigView::UpdateControls() {
  UpdateControlsToEnable();

  if (psk_passphrase_label_)
    psk_passphrase_label_->SetEnabled(enable_psk_passphrase_);
  if (psk_passphrase_textfield_)
    psk_passphrase_textfield_->SetEnabled(enable_psk_passphrase_ &&
                                          psk_passphrase_ui_data_.IsEditable());

  if (user_cert_label_)
    user_cert_label_->SetEnabled(enable_user_cert_);
  if (user_cert_combobox_)
    user_cert_combobox_->SetEnabled(enable_user_cert_ &&
                                    user_cert_ui_data_.IsEditable());

  if (server_ca_cert_label_)
    server_ca_cert_label_->SetEnabled(enable_server_ca_cert_);
  if (server_ca_cert_combobox_)
    server_ca_cert_combobox_->SetEnabled(enable_server_ca_cert_ &&
                                         ca_cert_ui_data_.IsEditable());

  if (otp_label_)
    otp_label_->SetEnabled(enable_otp_);
  if (otp_textfield_)
    otp_textfield_->SetEnabled(enable_otp_);

  if (group_name_label_)
    group_name_label_->SetEnabled(enable_group_name_);
  if (group_name_textfield_)
    group_name_textfield_->SetEnabled(enable_group_name_ &&
                                      group_name_ui_data_.IsEditable());
}

void VPNConfigView::UpdateErrorLabel() {
  // Error message.
  string16 error_msg;
  bool cert_required =
      GetProviderTypeIndex() == PROVIDER_TYPE_INDEX_L2TP_IPSEC_USER_CERT;
  if (cert_required && CertLibrary::Get()->CertificatesLoaded()) {
    if (!HaveUserCerts()) {
      error_msg = l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
    } else if (!IsUserCertValid()) {
      error_msg = l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_REQUIRE_HARDWARE_BACKED);
    }
  }
  if (error_msg.empty() && !service_path_.empty()) {
    // TODO(kuan): differentiate between bad psk and user passphrases.
    const NetworkState* vpn = NetworkHandler::Get()->network_state_handler()->
        GetNetworkState(service_path_);
    if (vpn && vpn->connection_state() == flimflam::kStateFailure)
      error_msg = ash::network_connect::ErrorString(vpn->error());
  }
  if (!error_msg.empty()) {
    error_label_->SetText(error_msg);
    error_label_->SetVisible(true);
  } else {
    error_label_->SetVisible(false);
  }
}

void VPNConfigView::UpdateCanLogin() {
  parent_->GetDialogClientView()->UpdateDialogButtons();
}

bool VPNConfigView::HaveUserCerts() const {
  return CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) > 0;
}

bool VPNConfigView::IsUserCertValid() const {
  if (!user_cert_combobox_ || !enable_user_cert_)
    return false;
  int index = user_cert_combobox_->selected_index();
  if (index < 0)
    return false;
  // Currently only hardware-backed user certificates are valid.
  if (CertLibrary::Get()->IsHardwareBacked() &&
      !CertLibrary::Get()->IsCertHardwareBackedAt(
          CertLibrary::CERT_TYPE_USER, index))
    return false;
  return true;
}

const std::string VPNConfigView::GetTextFromField(views::Textfield* textfield,
                                                  bool trim_whitespace) const {
  if (!textfield)
    return std::string();
  std::string untrimmed = UTF16ToUTF8(textfield->text());
  if (!trim_whitespace)
    return untrimmed;
  std::string result;
  TrimWhitespaceASCII(untrimmed, TRIM_ALL, &result);
  return result;
}

const std::string VPNConfigView::GetPassphraseFromField(
    PassphraseTextfield* textfield) const {
  if (!textfield)
    return std::string();
  return textfield->GetPassphrase();
}

void VPNConfigView::ParseVPNUIProperty(
    const NetworkState* network,
    const std::string& dict_key,
    const std::string& key,
    NetworkPropertyUIData* property_ui_data) {
  onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
  const base::DictionaryValue* onc =
      onc::FindPolicyForActiveUser(network->guid(), &onc_source);

  VLOG_IF(1, !onc) << "No ONC found for VPN network " << network->guid();
  property_ui_data->ParseOncProperty(
      onc_source,
      onc,
      base::StringPrintf("%s.%s.%s",
                         onc::network_config::kVPN,
                         dict_key.c_str(),
                         key.c_str()));
}

}  // namespace chromeos
