// Copyright 2014 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 "athena/system/network_selector.h"

#include "base/memory/weak_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/network/network_configuration_handler.h"
#include "chromeos/network/network_connection_handler.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_state_handler_observer.h"
#include "chromeos/network/network_type_pattern.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/aura/window.h"
#include "ui/chromeos/network/network_icon.h"
#include "ui/chromeos/network/network_info.h"
#include "ui/chromeos/network/network_list.h"
#include "ui/chromeos/network/network_list_delegate.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/blue_button.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"

using chromeos::NetworkConfigurationHandler;
using chromeos::NetworkConnectionHandler;
using chromeos::NetworkHandler;
using chromeos::NetworkProfileHandler;
using chromeos::NetworkState;

namespace {

const int kBackgroundColor = SkColorSetARGB(0x7f, 0, 0, 0);

// The View for the user to enter the password for connceting to a network. This
// view also shows an error message if the network connection fails.
class PasswordView : public views::View, public views::ButtonListener {
 public:
  PasswordView(const ui::NetworkInfo& network,
               const base::Callback<void(bool)>& callback,
               views::View* parent_container)
      : network_(network),
        callback_(callback),
        parent_container_(parent_container),
        connect_(NULL),
        cancel_(NULL),
        textfield_(NULL),
        error_msg_(NULL),
        weak_ptr_(this) {
    const int kHorizontal = 5;
    const int kVertical = 0;
    const int kPadding = 0;

    views::BoxLayout* layout = new views::BoxLayout(
        views::BoxLayout::kVertical, kHorizontal, kVertical, kPadding);
    layout->set_main_axis_alignment(
        views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
    layout->set_cross_axis_alignment(
        views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
    SetLayoutManager(layout);

    views::View* container = new views::View;
    layout = new views::BoxLayout(
        views::BoxLayout::kHorizontal, kHorizontal, kVertical, kPadding);
    layout->set_main_axis_alignment(
        views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
    container->SetLayoutManager(layout);

    textfield_ = new views::Textfield();
    textfield_->set_placeholder_text(base::ASCIIToUTF16("Password"));
    textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
    textfield_->set_default_width_in_chars(35);
    container->AddChildView(textfield_);

    connect_ = new views::BlueButton(this, base::ASCIIToUTF16("Connect"));
    container->AddChildView(connect_);

    cancel_ = new views::LabelButton(this, base::ASCIIToUTF16("Cancel"));
    cancel_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
    container->AddChildView(cancel_);

    AddChildView(container);
  }

  virtual ~PasswordView() {}

 private:
  void Close(bool successful) { callback_.Run(successful); }

  void OnKnownError(const std::string& error_name,
                    scoped_ptr<base::DictionaryValue> error_data) {
    std::string message;
    if (!error_data->GetString(chromeos::network_handler::kDbusErrorMessage,
                               &message))
      message = error_name;
    if (message.empty())
      message = std::string("Unknown error.");
    if (!error_msg_) {
      error_msg_ = new views::Label();
      error_msg_->SetFontList(
          error_msg_->font_list().Derive(0, gfx::Font::BOLD));
      error_msg_->SetEnabledColor(SK_ColorRED);
    }
    error_msg_->SetText(base::UTF8ToUTF16(message));
    if (!error_msg_->parent()) {
      AddChildView(error_msg_);
      InvalidateLayout();
      parent_container_->Layout();
      ScrollRectToVisible(error_msg_->bounds());
    }
    connect_->SetEnabled(true);
  }

  void OnSetProfileSucceed(const base::string16& password) {
    base::DictionaryValue properties;
    properties.SetStringWithoutPathExpansion(shill::kPassphraseProperty,
                                             textfield_->text());
    NetworkHandler::Get()->network_configuration_handler()->SetProperties(
        network_.service_path,
        properties,
        base::Bind(&PasswordView::OnSetPropertiesSucceed,
                   weak_ptr_.GetWeakPtr()),
        base::Bind(&PasswordView::OnKnownError, weak_ptr_.GetWeakPtr()));
  }

  void OnSetPropertiesSucceed() {
    const bool check_error_state = false;
    NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
        network_.service_path,
        base::Bind(&PasswordView::OnConnectionSucceed, weak_ptr_.GetWeakPtr()),
        base::Bind(&PasswordView::OnKnownError, weak_ptr_.GetWeakPtr()),
        check_error_state);
  }

  void OnConnectionSucceed() { Close(true); }

  // views::View:
  virtual void ViewHierarchyChanged(
      const views::View::ViewHierarchyChangedDetails& details) override {
    if (details.is_add && details.child == this)
      textfield_->RequestFocus();
  }

  // views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender,
                             const ui::Event& event) override {
    if (sender == connect_) {
      if (error_msg_) {
        RemoveChildView(error_msg_);
        delete error_msg_;
        error_msg_ = NULL;
      }
      connect_->SetEnabled(false);
      NetworkHandler::Get()->network_configuration_handler()->SetNetworkProfile(
          network_.service_path,
          NetworkProfileHandler::GetSharedProfilePath(),
          base::Bind(&PasswordView::OnSetProfileSucceed,
                     weak_ptr_.GetWeakPtr(),
                     textfield_->text()),
          base::Bind(&PasswordView::OnKnownError, weak_ptr_.GetWeakPtr()));
    } else if (sender == cancel_) {
      Close(false);
    } else {
      NOTREACHED();
    }
  }

  ui::NetworkInfo network_;
  base::Callback<void(bool)> callback_;
  views::View* parent_container_;

  views::BlueButton* connect_;
  views::LabelButton* cancel_;
  views::Textfield* textfield_;
  views::Label* error_msg_;
  base::WeakPtrFactory<PasswordView> weak_ptr_;

  DISALLOW_COPY_AND_ASSIGN(PasswordView);
};

// A View that represents a single row in the network list. This row also
// contains the View for taking password for password-protected networks.
class NetworkRow : public views::View {
 public:
  NetworkRow(const ui::NetworkInfo& network, views::View* container)
      : network_(network), container_(container), weak_ptr_(this) {
    SetBorder(views::Border::CreateEmptyBorder(10, 5, 10, 5));
    SetLayoutManager(
        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 10));
    Update(network);
  }

  virtual ~NetworkRow() {}

  void Update(const ui::NetworkInfo& network) {
    network_ = network;
    views::ImageView* icon = new views::ImageView();
    icon->SetImage(network.image);
    icon->SetBounds(0, 0, network.image.width(), network.image.height());

    views::Label* label = new views::Label(network.label);
    if (network.highlight)
      label->SetFontList(label->font_list().Derive(0, gfx::Font::BOLD));
    AddChildView(icon);
    AddChildView(label);
    if (password_view_)
      AddChildView(password_view_.get());
  }

  bool has_password_view() const { return password_view_; }

 private:
  void OnPasswordComplete(bool successful) {
    password_view_.reset();
    InvalidateLayout();
    container_->Layout();
    ScrollRectToVisible(GetContentsBounds());
  }

  void ShowPasswordView(const std::string& service_path) {
    const NetworkState* network =
        NetworkHandler::Get()->network_state_handler()->GetNetworkState(
            service_path);
    if (!network)
      return;

    // If this is not a wifi network that needs a password, then ignore.
    if (network->type() != shill::kTypeWifi ||
        network->security() == shill::kSecurityNone) {
      return;
    }

    password_view_.reset(new PasswordView(
        network_,
        base::Bind(&NetworkRow::OnPasswordComplete, weak_ptr_.GetWeakPtr()),
        container_));
    password_view_->set_owned_by_client();
    AddChildView(password_view_.get());
    PreferredSizeChanged();
    container_->Layout();
    ScrollRectToVisible(password_view_->bounds());
  }

  void OnNetworkConnectionError(const std::string& service_path,
                                const std::string& error_name,
                                scoped_ptr<base::DictionaryValue> error_data) {
    if (error_name == NetworkConnectionHandler::kErrorConnectCanceled)
      return;
    if (error_name == shill::kErrorBadPassphrase ||
        error_name == NetworkConnectionHandler::kErrorPassphraseRequired ||
        error_name == NetworkConnectionHandler::kErrorConfigurationRequired ||
        error_name == NetworkConnectionHandler::kErrorAuthenticationRequired) {
      ShowPasswordView(service_path);
    }
  }

  void ActivateNetwork() {
    const chromeos::NetworkState* network =
        NetworkHandler::Get()->network_state_handler()->GetNetworkState(
            network_.service_path);
    if (!network)
      return;
    if (network->IsConnectedState()) {
      NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
          network_.service_path,
          base::Closure(),
          chromeos::network_handler::ErrorCallback());
    } else if (!network->IsConnectingState()) {
      // |network| is not connected, and not already trying to connect.
      NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
          network_.service_path,
          base::Closure(),
          base::Bind(&NetworkRow::OnNetworkConnectionError,
                     weak_ptr_.GetWeakPtr(),
                     network_.service_path),
          false);
    }
  }

  // views::View:
  virtual void OnMouseEvent(ui::MouseEvent* event) override {
    if (event->type() != ui::ET_MOUSE_PRESSED)
      return;
    ActivateNetwork();
    event->SetHandled();
  }

  virtual void OnGestureEvent(ui::GestureEvent* gesture) override {
    if (gesture->type() != ui::ET_GESTURE_TAP)
      return;
    ActivateNetwork();
    gesture->SetHandled();
  }

  ui::NetworkInfo network_;
  views::View* container_;
  scoped_ptr<views::View> password_view_;
  base::WeakPtrFactory<NetworkRow> weak_ptr_;

  DISALLOW_COPY_AND_ASSIGN(NetworkRow);
};

class NetworkSelector : public ui::NetworkListDelegate,
                        public chromeos::NetworkStateHandlerObserver,
                        public ui::EventHandler {
 public:
  explicit NetworkSelector(aura::Window* container)
      : background_view_(NULL),
        scroll_content_(NULL),
        scroller_(NULL),
        network_list_(this) {
    CreateWidget(container);
    CreateNetworkList();

    NetworkHandler::Get()->network_state_handler()->RequestScan();
    NetworkHandler::Get()->network_state_handler()->AddObserver(this,
                                                                FROM_HERE);
  }

  virtual ~NetworkSelector() {
    NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
                                                                   FROM_HERE);
  }

 private:
  void CreateWidget(aura::Window* container) {
    views::Widget::InitParams params;
    params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
    params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
    params.activatable = views::Widget::InitParams::ACTIVATABLE_DEFAULT;
    params.accept_events = true;
    params.bounds = gfx::Rect(container->bounds().size());
    params.parent = container;
    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    widget_.reset(new views::Widget());
    widget_->Init(params);
    widget_->Show();

    background_view_ = new views::View;
    background_view_->set_background(
        views::Background::CreateSolidBackground(kBackgroundColor));
    background_view_->SetBorder(
        views::Border::CreateEmptyBorder(100, 300, 300, 300));
    background_view_->SetLayoutManager(new views::FillLayout());
    background_view_->set_target_handler(this);

    widget_->SetContentsView(background_view_);
  }

  void CreateNetworkList() {
    const int kListHeight = 500;
    scroller_ = new views::ScrollView();
    scroller_->set_background(
        views::Background::CreateSolidBackground(SK_ColorWHITE));
    scroller_->SetBounds(0, 0, 400, kListHeight);

    scroll_content_ = new views::View;
    scroll_content_->SetLayoutManager(
        new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
    scroller_->SetContents(scroll_content_);

    scroller_->ClipHeightTo(kListHeight, kListHeight);
    scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false));
    background_view_->AddChildView(scroller_);

    background_view_->Layout();

    network_list_.set_content_view(scroll_content_);
  }

  void UpdateNetworkList() { network_list_.UpdateNetworkList(); }

  void Close() { delete this; }

  // ui::NetworkListDelegate:
  virtual views::View* CreateViewForNetwork(
      const ui::NetworkInfo& info) override {
    return new NetworkRow(info, background_view_);
  }

  virtual bool IsViewHovered(views::View* view) override {
    return static_cast<NetworkRow*>(view)->has_password_view();
  }

  virtual chromeos::NetworkTypePattern GetNetworkTypePattern() const override {
    return chromeos::NetworkTypePattern::NonVirtual();
  }

  virtual void UpdateViewForNetwork(views::View* view,
                                    const ui::NetworkInfo& info) override {
    static_cast<NetworkRow*>(view)->Update(info);
  }

  virtual views::Label* CreateInfoLabel() override {
    views::Label* label = new views::Label();
    return label;
  }

  virtual void RelayoutScrollList() override { scroller_->Layout(); }

  // chromeos::NetworkStateHandlerObserver:
  virtual void NetworkListChanged() override { UpdateNetworkList(); }

  virtual void DeviceListChanged() override {}

  virtual void DefaultNetworkChanged(
      const chromeos::NetworkState* network) override {}

  virtual void NetworkConnectionStateChanged(
      const chromeos::NetworkState* network) override {}

  virtual void NetworkPropertiesUpdated(
      const chromeos::NetworkState* network) override {}

  // ui::EventHandler:
  virtual void OnMouseEvent(ui::MouseEvent* mouse) override {
    CHECK_EQ(background_view_, mouse->target());
    if (mouse->type() == ui::ET_MOUSE_PRESSED && !mouse->handled()) {
      Close();
      mouse->SetHandled();
    }
  }

  virtual void OnGestureEvent(ui::GestureEvent* gesture) override {
    CHECK_EQ(background_view_, gesture->target());
    if (gesture->type() == ui::ET_GESTURE_TAP && !gesture->handled()) {
      Close();
      gesture->SetHandled();
    }
  }

  scoped_ptr<views::Widget> widget_;
  views::View* background_view_;
  views::View* scroll_content_;
  views::ScrollView* scroller_;

  views::View* connect_;

  ui::NetworkListView network_list_;

  DISALLOW_COPY_AND_ASSIGN(NetworkSelector);
};

}  // namespace

namespace athena {

void CreateNetworkSelector(aura::Window* container) {
  new NetworkSelector(container);
}

}  // namespace athena
