// 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 "ash/system/network/network_state_list_detailed_view.h"

#include <algorithm>

#include "ash/metrics/user_metrics_recorder.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/tray/system_menu_button.h"
#include "ash/system/tray/tri_view.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_connect.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/layout_manager.h"
#include "ui/views/widget/widget.h"

using chromeos::DeviceState;
using chromeos::NetworkHandler;
using chromeos::NetworkState;
using chromeos::NetworkStateHandler;
using chromeos::NetworkTypePattern;

namespace ash {
namespace tray {
namespace {

// Delay between scan requests.
constexpr int kRequestScanDelaySeconds = 10;

// This margin value is used throughout the bubble:
// - margins inside the border
// - horizontal spacing between bubble border and parent bubble border
// - distance between top of this bubble's border and the bottom of the anchor
//   view (horizontal rule).
constexpr int kBubbleMargin = 8;

// Elevation used for the bubble shadow effect (tiny).
constexpr int kBubbleShadowElevation = 2;

bool IsSecondaryUser() {
  SessionController* session_controller = Shell::Get()->session_controller();
  return session_controller->IsActiveUserSessionStarted() &&
         !session_controller->IsUserPrimary();
}

bool IsWifiEnabled() {
  return NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled(
      chromeos::NetworkTypePattern::WiFi());
}

}  // namespace

// A bubble which displays network info.
class NetworkStateListDetailedView::InfoBubble
    : public views::BubbleDialogDelegateView {
 public:
  InfoBubble(views::View* anchor,
             views::View* content,
             NetworkStateListDetailedView* detailed_view)
      : views::BubbleDialogDelegateView(anchor, views::BubbleBorder::TOP_RIGHT),
        detailed_view_(detailed_view) {
    set_margins(gfx::Insets(kBubbleMargin));
    SetArrow(views::BubbleBorder::NONE);
    set_shadow(views::BubbleBorder::NO_ASSETS);
    set_anchor_view_insets(gfx::Insets(0, 0, kBubbleMargin, 0));
    set_notify_enter_exit_on_child(true);
    SetLayoutManager(std::make_unique<views::FillLayout>());
    AddChildView(content);
  }

  ~InfoBubble() override {
    // The detailed view can be destructed before info bubble is destructed.
    // Call OnInfoBubbleDestroyed only if the detailed view is live.
    if (detailed_view_)
      detailed_view_->OnInfoBubbleDestroyed();
  }

  void OnNetworkStateListDetailedViewIsDeleting() { detailed_view_ = nullptr; }

 private:
  // View:
  gfx::Size CalculatePreferredSize() const override {
    // This bubble should be inset by kBubbleMargin on both left and right
    // relative to the parent bubble.
    const gfx::Size anchor_size = GetAnchorView()->size();
    int contents_width =
        anchor_size.width() - 2 * kBubbleMargin - margins().width();
    return gfx::Size(contents_width, GetHeightForWidth(contents_width));
  }

  void OnMouseExited(const ui::MouseEvent& event) override {
    // Like the user switching bubble/menu, hide the bubble when the mouse
    // exits.
    if (detailed_view_)
      detailed_view_->ResetInfoBubble();
  }

  // BubbleDialogDelegateView:
  int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; }

  void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
                                views::Widget* widget) const override {
    params->shadow_type = views::Widget::InitParams::SHADOW_TYPE_DROP;
    params->shadow_elevation = kBubbleShadowElevation;
    params->name = "NetworkStateListDetailedView::InfoBubble";
  }

  // Not owned.
  NetworkStateListDetailedView* detailed_view_;

  DISALLOW_COPY_AND_ASSIGN(InfoBubble);
};

//------------------------------------------------------------------------------

// Special layout to overlap the scanning throbber and the info button.
class InfoThrobberLayout : public views::LayoutManager {
 public:
  InfoThrobberLayout() = default;
  ~InfoThrobberLayout() override = default;

  // views::LayoutManager
  void Layout(views::View* host) override {
    gfx::Size max_size(GetMaxChildSize(host));
    // Center each child view within |max_size|.
    for (int i = 0; i < host->child_count(); ++i) {
      views::View* child = host->child_at(i);
      if (!child->visible())
        continue;
      gfx::Size child_size = child->GetPreferredSize();
      gfx::Point origin;
      origin.set_x((max_size.width() - child_size.width()) / 2);
      origin.set_y((max_size.height() - child_size.height()) / 2);
      gfx::Rect bounds(origin, child_size);
      bounds.Inset(-host->GetInsets());
      child->SetBoundsRect(bounds);
    }
  }

  gfx::Size GetPreferredSize(const views::View* host) const override {
    gfx::Point origin;
    gfx::Rect rect(origin, GetMaxChildSize(host));
    rect.Inset(-host->GetInsets());
    return rect.size();
  }

 private:
  gfx::Size GetMaxChildSize(const views::View* host) const {
    int width = 0, height = 0;
    for (int i = 0; i < host->child_count(); ++i) {
      const views::View* child = host->child_at(i);
      if (!child->visible())
        continue;
      gfx::Size child_size = child->GetPreferredSize();
      width = std::max(width, child_size.width());
      height = std::max(height, child_size.width());
    }
    return gfx::Size(width, height);
  }

  DISALLOW_COPY_AND_ASSIGN(InfoThrobberLayout);
};

//------------------------------------------------------------------------------
// NetworkStateListDetailedView

NetworkStateListDetailedView::NetworkStateListDetailedView(
    DetailedViewDelegate* delegate,
    ListType list_type,
    LoginStatus login)
    : TrayDetailedView(delegate),
      list_type_(list_type),
      login_(login),
      info_button_(nullptr),
      settings_button_(nullptr),
      info_bubble_(nullptr) {}

NetworkStateListDetailedView::~NetworkStateListDetailedView() {
  if (info_bubble_)
    info_bubble_->OnNetworkStateListDetailedViewIsDeleting();
  ResetInfoBubble();
}

void NetworkStateListDetailedView::Update() {
  UpdateNetworkList();
  UpdateHeaderButtons();
  UpdateScanningBar();
  Layout();
}

void NetworkStateListDetailedView::ToggleInfoBubbleForTesting() {
  ToggleInfoBubble();
}

void NetworkStateListDetailedView::Init() {
  CreateScrollableList();
  CreateTitleRow(list_type_ == ListType::LIST_TYPE_NETWORK
                     ? IDS_ASH_STATUS_TRAY_NETWORK
                     : IDS_ASH_STATUS_TRAY_VPN);

  Update();

  if (list_type_ == LIST_TYPE_NETWORK && IsWifiEnabled())
    ScanAndStartTimer();
}

void NetworkStateListDetailedView::HandleButtonPressed(views::Button* sender,
                                                       const ui::Event& event) {
  if (sender == info_button_) {
    ToggleInfoBubble();
    return;
  }

  if (sender == settings_button_)
    ShowSettings();

  CloseBubble();
}

void NetworkStateListDetailedView::HandleViewClicked(views::View* view) {
  if (login_ == LoginStatus::LOCKED)
    return;

  std::string guid;
  if (!IsNetworkEntry(view, &guid))
    return;

  const NetworkState* network =
      NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid(
          guid);
  bool can_connect = network && !network->IsConnectingOrConnected();
  if (network) {
    if (network->IsDefaultCellular())
      can_connect = false;  // Default Cellular network is not connectable.
    if (!network->connectable() && IsSecondaryUser()) {
      // Secondary users can only connect to fully configured networks.
      can_connect = false;
    }
  }
  if (can_connect) {
    Shell::Get()->metrics()->RecordUserMetricsAction(
        list_type_ == LIST_TYPE_VPN
            ? UMA_STATUS_AREA_CONNECT_TO_VPN
            : UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK);
    chromeos::NetworkConnect::Get()->ConnectToNetworkId(network->guid());
    return;
  }
  Shell::Get()->metrics()->RecordUserMetricsAction(
      list_type_ == LIST_TYPE_VPN
          ? UMA_STATUS_AREA_SHOW_VPN_CONNECTION_DETAILS
          : UMA_STATUS_AREA_SHOW_NETWORK_CONNECTION_DETAILS);
  Shell::Get()->system_tray_model()->client_ptr()->ShowNetworkSettings(
      network ? network->guid() : std::string());
}

void NetworkStateListDetailedView::CreateExtraTitleRowButtons() {
  if (login_ == LoginStatus::LOCKED)
    return;

  DCHECK(!info_button_);
  tri_view()->SetContainerVisible(TriView::Container::END, true);

  info_button_ = CreateInfoButton(IDS_ASH_STATUS_TRAY_NETWORK_INFO);
  tri_view()->AddView(TriView::Container::END, info_button_);

  DCHECK(!settings_button_);
  settings_button_ = CreateSettingsButton(IDS_ASH_STATUS_TRAY_NETWORK_SETTINGS);
  tri_view()->AddView(TriView::Container::END, settings_button_);
}

void NetworkStateListDetailedView::ShowSettings() {
  Shell::Get()->metrics()->RecordUserMetricsAction(
      list_type_ == LIST_TYPE_VPN ? UMA_STATUS_AREA_VPN_SETTINGS_OPENED
                                  : UMA_STATUS_AREA_NETWORK_SETTINGS_OPENED);
  Shell::Get()->system_tray_model()->client_ptr()->ShowNetworkSettings(
      std::string());
}

void NetworkStateListDetailedView::UpdateHeaderButtons() {
  if (settings_button_) {
    if (login_ == LoginStatus::NOT_LOGGED_IN) {
      // When not logged in, only enable the settings button if there is a
      // default (i.e. connected or connecting) network to show settings for.
      settings_button_->SetEnabled(
          !!NetworkHandler::Get()->network_state_handler()->DefaultNetwork());
    } else {
      // Otherwise, enable if showing settings is allowed. There are situations
      // (supervised user creation flow) when the session is started but UI flow
      // continues within login UI, i.e., no browser window is yet available.
      settings_button_->SetEnabled(
          Shell::Get()->session_controller()->ShouldEnableSettings());
    }
  }
}

void NetworkStateListDetailedView::UpdateScanningBar() {
  if (list_type_ != LIST_TYPE_NETWORK)
    return;

  bool is_wifi_enabled = IsWifiEnabled();
  if (is_wifi_enabled && !network_scan_repeating_timer_.IsRunning())
    ScanAndStartTimer();

  if (!is_wifi_enabled && network_scan_repeating_timer_.IsRunning())
    network_scan_repeating_timer_.Stop();

  const bool scanning_bar_visible =
      is_wifi_enabled &&
      NetworkHandler::Get()->network_state_handler()->GetScanningByType(
          NetworkTypePattern::WiFi() | NetworkTypePattern::Tether());

  ShowProgress(-1, scanning_bar_visible);
}

void NetworkStateListDetailedView::ToggleInfoBubble() {
  if (ResetInfoBubble())
    return;

  info_bubble_ = new InfoBubble(tri_view(), CreateNetworkInfoView(), this);
  views::BubbleDialogDelegateView::CreateBubble(info_bubble_)->Show();
  info_bubble_->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, false);
}

bool NetworkStateListDetailedView::ResetInfoBubble() {
  if (!info_bubble_)
    return false;

  info_bubble_->GetWidget()->Close();
  return true;
}

void NetworkStateListDetailedView::OnInfoBubbleDestroyed() {
  info_bubble_ = nullptr;

  // Widget of info bubble is activated while info bubble is shown. To move
  // focus back to the widget of this view, activate it again here.
  GetWidget()->Activate();
}

views::View* NetworkStateListDetailedView::CreateNetworkInfoView() {
  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();

  std::string ip_address, ipv6_address;
  const NetworkState* network = handler->DefaultNetwork();
  if (network) {
    ip_address = network->GetIpAddress();
    const DeviceState* device = handler->GetDeviceState(network->device_path());
    if (device)
      ipv6_address = device->GetIpAddressByType(shill::kTypeIPv6);
  }

  std::string ethernet_address, wifi_address;
  if (list_type_ == LIST_TYPE_NETWORK) {
    ethernet_address = handler->FormattedHardwareAddressForType(
        NetworkTypePattern::Ethernet());
    wifi_address =
        handler->FormattedHardwareAddressForType(NetworkTypePattern::WiFi());
  }

  base::string16 bubble_text;
  auto add_line = [&bubble_text](const std::string& address, int ids) {
    if (!address.empty()) {
      if (!bubble_text.empty())
        bubble_text += base::ASCIIToUTF16("\n");

      bubble_text +=
          l10n_util::GetStringFUTF16(ids, base::UTF8ToUTF16(address));
    }
  };

  add_line(ip_address, IDS_ASH_STATUS_TRAY_IP_ADDRESS);
  add_line(ipv6_address, IDS_ASH_STATUS_TRAY_IPV6_ADDRESS);
  add_line(ethernet_address, IDS_ASH_STATUS_TRAY_ETHERNET_ADDRESS);
  add_line(wifi_address, IDS_ASH_STATUS_TRAY_WIFI_ADDRESS);

  // Avoid an empty bubble in the unlikely event that there is no network
  // information at all.
  if (bubble_text.empty())
    bubble_text = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_NETWORKS);

  auto* label = new views::Label(bubble_text);
  label->SetMultiLine(true);
  label->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
  label->SetSelectable(true);
  return label;
}

void NetworkStateListDetailedView::ScanAndStartTimer() {
  CallRequestScan();
  network_scan_repeating_timer_.Start(
      FROM_HERE, base::TimeDelta::FromSeconds(kRequestScanDelaySeconds), this,
      &NetworkStateListDetailedView::CallRequestScan);
}

void NetworkStateListDetailedView::CallRequestScan() {
  if (!IsWifiEnabled())
    return;

  VLOG(1) << "Requesting Network Scan.";
  NetworkHandler::Get()->network_state_handler()->RequestScan(
      NetworkTypePattern::WiFi() | NetworkTypePattern::Tether());
}

}  // namespace tray
}  // namespace ash
