// Copyright 2020 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/phonehub/phone_status_view.h"

#include <string>

#include "ash/public/cpp/network_icon_image_source.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/root_window_controller.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/phonehub/phone_hub_tray.h"
#include "ash/system/phonehub/phone_hub_view_ids.h"
#include "ash/system/power/battery_image_source.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "base/i18n/number_formatting.h"
#include "base/strings/strcat.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/box_layout.h"

namespace ash {

using PhoneStatusModel = chromeos::phonehub::PhoneStatusModel;

namespace {

// Appearance in Dip.
constexpr int kTitleContainerSpacing = 16;
constexpr int kStatusSpacing = 4;
constexpr gfx::Size kStatusIconSize(kUnifiedTrayIconSize, kUnifiedTrayIconSize);
constexpr gfx::Size kSignalIconSize(15, 15);
constexpr int kSeparatorHeight = 18;
constexpr int kPhoneNameLabelWidthMax = 160;
constexpr gfx::Insets kBorderInsets(0, 16);
constexpr gfx::Insets kBatteryLabelBorderInsets(0, 0, 0, 4);

// Typograph in dip.
constexpr int kBatteryLabelFontSize = 11;

// Multiplied by the int returned by GetSignalStrengthAsInt() to obtain a
// percentage for the signal strength displayed by the tooltip when hovering
// over the signal strength icon, and verbalized by ChromeVox.
constexpr int kSignalStrengthToPercentageMultiplier = 25;

int GetSignalStrengthAsInt(PhoneStatusModel::SignalStrength signal_strength) {
  switch (signal_strength) {
    case PhoneStatusModel::SignalStrength::kZeroBars:
      return 0;
    case PhoneStatusModel::SignalStrength::kOneBar:
      return 1;
    case PhoneStatusModel::SignalStrength::kTwoBars:
      return 2;
    case PhoneStatusModel::SignalStrength::kThreeBars:
      return 3;
    case PhoneStatusModel::SignalStrength::kFourBars:
      return 4;
  }
}

// ImageSource for the battery icon.
class PhoneHubBatteryImageSource : public BatteryImageSource {
 public:
  PhoneHubBatteryImageSource(const PowerStatus::BatteryImageInfo& info,
                             int height,
                             SkColor bg_color,
                             SkColor fg_color,
                             bool in_battery_saver_mode)
      : BatteryImageSource(info, height, bg_color, fg_color),
        bg_color_(bg_color),
        in_battery_saver_mode_(in_battery_saver_mode) {}

  ~PhoneHubBatteryImageSource() override = default;

  // BatteryImageSource:
  void Draw(gfx::Canvas* canvas) override {
    BatteryImageSource::Draw(canvas);

    if (!in_battery_saver_mode_)
      return;

    SkColor saver_color = AshColorProvider::Get()->GetContentLayerColor(
        AshColorProvider::ContentLayerType::kIconColorWarning);

    gfx::ImageSkia icon = CreateVectorIcon(kBatteryIcon, saver_color);
    // Draw the solid outline of the battery icon.
    canvas->DrawImageInt(icon, 0, 0);

    PaintVectorIcon(canvas, kPhoneHubBatterySaverOutlineIcon, bg_color_);
    PaintVectorIcon(canvas, kPhoneHubBatterySaverIcon, saver_color);
  }

 private:
  const SkColor bg_color_;
  bool in_battery_saver_mode_ = false;
};

}  // namespace

PhoneStatusView::PhoneStatusView(chromeos::phonehub::PhoneModel* phone_model,
                                 Delegate* delegate)
    : TriView(kTitleContainerSpacing),
      phone_model_(phone_model),
      phone_name_label_(new views::Label),
      signal_icon_(new views::ImageView),
      battery_icon_(new views::ImageView),
      battery_label_(new views::Label) {
  DCHECK(delegate);

  SetPaintToLayer();
  layer()->SetFillsBoundsOpaquely(false);
  SetID(PhoneHubViewID::kPhoneStatusView);

  SetBorder(views::CreateEmptyBorder(kBorderInsets));

  // Phone name is placed at START container, Settings icon is
  // placed at END container, other phone states, i.e. battery level,
  // and Separator are placed at CENTER container.
  ConfigureTriViewContainer(TriView::Container::START);
  ConfigureTriViewContainer(TriView::Container::CENTER);
  ConfigureTriViewContainer(TriView::Container::END);

  phone_model_->AddObserver(this);

  phone_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  phone_name_label_->SetEnabledColor(
      AshColorProvider::Get()->GetContentLayerColor(
          AshColorProvider::ContentLayerType::kTextColorPrimary));
  TrayPopupUtils::SetLabelFontList(phone_name_label_,
                                   TrayPopupUtils::FontStyle::kSubHeader);
  phone_name_label_->SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL);
  AddView(TriView::Container::START, phone_name_label_);

  AddView(TriView::Container::CENTER, signal_icon_);
  AddView(TriView::Container::CENTER, battery_icon_);

  battery_label_->SetAutoColorReadabilityEnabled(false);
  battery_label_->SetSubpixelRenderingEnabled(false);
  battery_label_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kTextColorPrimary));
  auto default_font = battery_label_->font_list();
  battery_label_->SetFontList(default_font.DeriveWithSizeDelta(
      kBatteryLabelFontSize - default_font.GetFontSize()));
  battery_label_->SetBorder(
      views::CreateEmptyBorder(kBatteryLabelBorderInsets));
  AddView(TriView::Container::CENTER, battery_label_);

  separator_ = new views::Separator();
  separator_->SetColor(AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kSeparatorColor));
  separator_->SetPreferredHeight(kSeparatorHeight);
  AddView(TriView::Container::CENTER, separator_);

  settings_button_ = new TopShortcutButton(
      base::BindRepeating(&Delegate::OpenConnectedDevicesSettings,
                          base::Unretained(delegate)),
      kSystemMenuSettingsIcon,
      IDS_ASH_PHONE_HUB_CONNECTED_DEVICE_SETTINGS_LABEL);
  AddView(TriView::Container::END, settings_button_);

  separator_->SetVisible(delegate->CanOpenConnectedDeviceSettings());
  settings_button_->SetVisible(delegate->CanOpenConnectedDeviceSettings());

  Update();
}

PhoneStatusView::~PhoneStatusView() {
  phone_model_->RemoveObserver(this);
}

void PhoneStatusView::OnModelChanged() {
  Update();
}

void PhoneStatusView::Update() {
  // Set phone name text and elide it if needed.
  phone_name_label_->SetText(
      gfx::ElideText(phone_model_->phone_name().value_or(std::u16string()),
                     phone_name_label_->font_list(), kPhoneNameLabelWidthMax,
                     gfx::ELIDE_TAIL));

  // Clear the phone status if the status model returns null when the phone is
  // disconnected.
  if (!phone_model_->phone_status_model()) {
    ClearExistingStatus();
    // Hide separator if there is no preceding content.
    separator_->SetVisible(false);
    return;
  }

  UpdateMobileStatus();
  UpdateBatteryStatus();
}

void PhoneStatusView::UpdateMobileStatus() {
  const PhoneStatusModel& phone_status =
      phone_model_->phone_status_model().value();

  const SkColor primary_color = AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kIconColorPrimary);

  gfx::ImageSkia signal_image;
  std::u16string tooltip_text;
  switch (phone_status.mobile_status()) {
    case PhoneStatusModel::MobileStatus::kNoSim:
      signal_image = CreateVectorIcon(kPhoneHubMobileNoSimIcon, primary_color);
      tooltip_text =
          l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_MOBILE_STATUS_NO_SIM);
      signal_icon_->SetImageSize(kStatusIconSize);
      break;
    case PhoneStatusModel::MobileStatus::kSimButNoReception:
      signal_image =
          CreateVectorIcon(kPhoneHubMobileNoConnectionIcon, primary_color);
      tooltip_text =
          l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_MOBILE_STATUS_NO_NETWORK);
      signal_icon_->SetImageSize(kStatusIconSize);
      break;
    case PhoneStatusModel::MobileStatus::kSimWithReception:
      const PhoneStatusModel::MobileConnectionMetadata& metadata =
          phone_status.mobile_connection_metadata().value();
      int signal_strength = GetSignalStrengthAsInt(metadata.signal_strength);
      signal_image = gfx::CanvasImageSource::MakeImageSkia<
          network_icon::SignalStrengthImageSource>(
          network_icon::ImageType::BARS, primary_color, kSignalIconSize,
          signal_strength);
      signal_icon_->SetImageSize(kSignalIconSize);
      tooltip_text = l10n_util::GetStringFUTF16(
          IDS_ASH_PHONE_HUB_MOBILE_STATUS_NETWORK_NAME_AND_STRENGTH,
          metadata.mobile_provider,
          base::NumberToString16(signal_strength *
                                 kSignalStrengthToPercentageMultiplier));
      break;
  }

  signal_icon_->SetImage(signal_image);
  signal_icon_->SetTooltipText(tooltip_text);
}

void PhoneStatusView::UpdateBatteryStatus() {
  const PhoneStatusModel& phone_status =
      phone_model_->phone_status_model().value();

  const PowerStatus::BatteryImageInfo& info = CalculateBatteryInfo();

  const SkColor icon_bg_color = color_utils::GetResultingPaintColor(
      ShelfConfig::Get()->GetShelfControlButtonColor(),
      AshColorProvider::Get()->GetBackgroundColor());
  const SkColor icon_fg_color = AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kIconColorPrimary);

  bool in_battery_saver_mode = phone_status.battery_saver_state() ==
                               PhoneStatusModel::BatterySaverState::kOn;

  auto* source = new PhoneHubBatteryImageSource(info, kStatusIconSize.height(),
                                                icon_bg_color, icon_fg_color,
                                                in_battery_saver_mode);
  battery_icon_->SetImage(
      gfx::ImageSkia(base::WrapUnique(source), source->size()));
  SetBatteryTooltipText();
  battery_label_->SetText(
      base::FormatPercent(phone_status.battery_percentage()));
  battery_label_->SetAccessibleName(l10n_util::GetStringFUTF16(
      IDS_ASH_PHONE_HUB_BATTERY_PERCENTAGE_ACCESSIBLE_TEXT,
      base::NumberToString16(phone_status.battery_percentage())));
}

PowerStatus::BatteryImageInfo PhoneStatusView::CalculateBatteryInfo() {
  PowerStatus::BatteryImageInfo info;

  const PhoneStatusModel& phone_status =
      phone_model_->phone_status_model().value();

  info.charge_percent = phone_status.battery_percentage();

  switch (phone_status.charging_state()) {
    case PhoneStatusModel::ChargingState::kNotCharging:
      info.alert_if_low = true;
      if (info.charge_percent < PowerStatus::kCriticalBatteryChargePercentage) {
        info.icon_badge = &kUnifiedMenuBatteryAlertIcon;
        info.badge_outline = &kUnifiedMenuBatteryAlertOutlineIcon;
      }
      break;
    case PhoneStatusModel::ChargingState::kChargingAc:
      info.icon_badge = &kUnifiedMenuBatteryBoltIcon;
      info.badge_outline = &kUnifiedMenuBatteryBoltOutlineIcon;
      break;
    case PhoneStatusModel::ChargingState::kChargingUsb:
      info.icon_badge = &kUnifiedMenuBatteryUnreliableIcon;
      info.badge_outline = &kUnifiedMenuBatteryUnreliableOutlineIcon;
      break;
  }

  return info;
}

void PhoneStatusView::SetBatteryTooltipText() {
  const PhoneStatusModel& phone_status =
      phone_model_->phone_status_model().value();

  int charging_tooltip_id;
  switch (phone_status.charging_state()) {
    case PhoneStatusModel::ChargingState::kNotCharging:
      charging_tooltip_id = IDS_ASH_PHONE_HUB_BATTERY_STATUS_NOT_CHARGING;
      break;
    case PhoneStatusModel::ChargingState::kChargingAc:
      charging_tooltip_id = IDS_ASH_PHONE_HUB_BATTERY_STATUS_CHARGING_AC;
      break;
    case PhoneStatusModel::ChargingState::kChargingUsb:
      charging_tooltip_id = IDS_ASH_PHONE_HUB_BATTERY_STATUS_CHARGING_USB;
      break;
  }
  std::u16string charging_tooltip =
      l10n_util::GetStringUTF16(charging_tooltip_id);

  bool battery_saver_on = phone_status.battery_saver_state() ==
                          PhoneStatusModel::BatterySaverState::kOn;
  std::u16string batter_saver_tooltip =
      battery_saver_on
          ? l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_BATTERY_SAVER_ON)
          : l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_BATTERY_SAVER_OFF);

  battery_icon_->SetTooltipText(
      l10n_util::GetStringFUTF16(IDS_ASH_PHONE_HUB_BATTERY_TOOLTIP,
                                 charging_tooltip, batter_saver_tooltip));
}

void PhoneStatusView::ClearExistingStatus() {
  // Clear mobile status.
  signal_icon_->SetImage(gfx::ImageSkia());

  // Clear battery status.
  battery_icon_->SetImage(gfx::ImageSkia());
  battery_label_->SetText(std::u16string());
}

void PhoneStatusView::ConfigureTriViewContainer(TriView::Container container) {
  std::unique_ptr<views::BoxLayout> layout;

  switch (container) {
    case TriView::Container::START:
      SetFlexForContainer(TriView::Container::START, 1.f);

      layout = std::make_unique<views::BoxLayout>(
          views::BoxLayout::Orientation::kVertical);
      layout->set_main_axis_alignment(
          views::BoxLayout::MainAxisAlignment::kCenter);
      layout->set_cross_axis_alignment(
          views::BoxLayout::CrossAxisAlignment::kStretch);
      break;
    case TriView::Container::CENTER:
      layout = std::make_unique<views::BoxLayout>(
          views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
          kStatusSpacing);
      layout->set_main_axis_alignment(
          views::BoxLayout::MainAxisAlignment::kEnd);
      layout->set_cross_axis_alignment(
          views::BoxLayout::CrossAxisAlignment::kCenter);
      break;
    case TriView::Container::END:
      layout = std::make_unique<views::BoxLayout>(
          views::BoxLayout::Orientation::kHorizontal);
      layout->set_main_axis_alignment(
          views::BoxLayout::MainAxisAlignment::kCenter);
      layout->set_cross_axis_alignment(
          views::BoxLayout::CrossAxisAlignment::kCenter);
      break;
  }

  SetContainerLayout(container, std::move(layout));
  SetMinSize(container, gfx::Size(0, kUnifiedDetailedViewTitleRowHeight));
}

}  // namespace ash
