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

#include <memory>

#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/holding_space/holding_space_client.h"
#include "ash/public/cpp/holding_space/holding_space_constants.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_metrics.h"
#include "ash/public/cpp/holding_space/holding_space_prefs.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/holding_space/holding_space_tray_bubble.h"
#include "ash/system/holding_space/holding_space_tray_icon.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_container.h"
#include "base/containers/adapters.h"
#include "components/prefs/pref_change_registrar.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/metadata/metadata_impl_macros.h"
#include "ui/views/vector_icons.h"

namespace ash {
namespace {

using ::ui::mojom::DragOperation;

// Animation.
constexpr base::TimeDelta kAnimationDuration =
    base::TimeDelta::FromMilliseconds(167);

// Helpers ---------------------------------------------------------------------

// Animates the specified `view` to the given `target_opacity`.
void AnimateToTargetOpacity(views::View* view, float target_opacity) {
  DCHECK(view->layer());
  if (view->layer()->GetTargetOpacity() == target_opacity)
    return;

  ui::ScopedLayerAnimationSettings settings(view->layer()->GetAnimator());
  settings.SetPreemptionStrategy(
      ui::LayerAnimator::PreemptionStrategy::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
  settings.SetTransitionDuration(kAnimationDuration);

  view->layer()->SetOpacity(target_opacity);
}

// Returns the file paths extracted from the specified `data` which are *not*
// pinned to the attached holding space model.
std::vector<base::FilePath> ExtractUnpinnedFilePaths(
    const ui::OSExchangeData& data) {
  if (!data.HasFile())
    return {};

  std::vector<ui::FileInfo> filenames;
  if (!data.GetFilenames(&filenames))
    return {};

  HoldingSpaceModel* const model = HoldingSpaceController::Get()->model();

  std::vector<base::FilePath> unpinned_file_paths;
  for (const ui::FileInfo& filename : filenames) {
    const base::FilePath& file_path = filename.path;
    if (!model->ContainsItem(HoldingSpaceItem::Type::kPinnedFile, file_path))
      unpinned_file_paths.push_back(file_path);
  }

  return unpinned_file_paths;
}

// Returns whether previews are enabled.
bool IsPreviewsEnabled() {
  auto* prefs = Shell::Get()->session_controller()->GetActivePrefService();
  return features::IsTemporaryHoldingSpacePreviewsEnabled() && prefs &&
         holding_space_prefs::IsPreviewsEnabled(prefs);
}

// Returns whether the holding space model contains any finalized items.
bool ModelContainsFinalizedItems(HoldingSpaceModel* model) {
  for (const auto& item : model->items()) {
    if (item->IsFinalized())
      return true;
  }
  return false;
}

// Creates the default tray icon.
std::unique_ptr<views::ImageView> CreateDefaultTrayIcon() {
  auto icon = std::make_unique<views::ImageView>();
  icon->SetID(kHoldingSpaceTrayDefaultIconId);
  icon->SetImage(gfx::CreateVectorIcon(
      kHoldingSpaceIcon, kHoldingSpaceTrayIconSize,
      AshColorProvider::Get()->GetContentLayerColor(
          AshColorProvider::ContentLayerType::kIconColorPrimary)));
  icon->SetPreferredSize(gfx::Size(kTrayItemSize, kTrayItemSize));
  icon->SetPaintToLayer();
  icon->layer()->SetFillsBoundsOpaquely(false);
  return icon;
}

// Creates the overlay to be drawn over all other child views to indicate that
// the parent view is a drop target and is capable of handling the current drag
// payload.
std::unique_ptr<views::View> CreateDropTargetOverlay() {
  auto drop_target_overlay = std::make_unique<views::View>();
  drop_target_overlay->SetID(kHoldingSpaceTrayDropTargetOverlayId);
  drop_target_overlay->SetLayoutManager(std::make_unique<views::FillLayout>());

  // Layer.
  drop_target_overlay->SetPaintToLayer();
  drop_target_overlay->layer()->SetFillsBoundsOpaquely(false);

  // Icon.
  auto* icon =
      drop_target_overlay->AddChildView(std::make_unique<views::ImageView>());
  icon->SetHorizontalAlignment(views::ImageView::Alignment::kCenter);
  icon->SetVerticalAlignment(views::ImageView::Alignment::kCenter);
  icon->SetImage(gfx::CreateVectorIcon(
      views::kUnpinIcon, kHoldingSpaceIconSize,
      AshColorProvider::Get()->GetContentLayerColor(
          AshColorProvider::ContentLayerType::kIconColorPrimary)));
  icon->SetPaintToLayer();
  icon->layer()->SetFillsBoundsOpaquely(false);

  return drop_target_overlay;
}

}  // namespace

// HoldingSpaceTray ------------------------------------------------------------

HoldingSpaceTray::HoldingSpaceTray(Shelf* shelf) : TrayBackgroundView(shelf) {
  controller_observer_.Observe(HoldingSpaceController::Get());
  session_observer_.Observe(Shell::Get()->session_controller());
  SetVisible(false);

  // Icon.
  default_tray_icon_ = tray_container()->AddChildView(CreateDefaultTrayIcon());

  if (features::IsTemporaryHoldingSpacePreviewsEnabled()) {
    previews_tray_icon_ = tray_container()->AddChildView(
        std::make_unique<HoldingSpaceTrayIcon>(shelf));
    previews_tray_icon_->SetVisible(false);

    // Enable context menu, which supports an action to toggle item previews.
    set_context_menu_controller(this);
  }

  // Drop target overlay.
  // NOTE: The `drop_target_overlay_` will only be visible when:
  //   * a drag is in progress,
  //   * the drag payload contains pinnable files, and
  //   * the cursor is sufficiently close to this view.
  drop_target_overlay_ = AddChildView(CreateDropTargetOverlay());
  drop_target_overlay_->layer()->SetOpacity(0.f);

  // Animation.
  set_use_bounce_in_animation(true);
}

HoldingSpaceTray::~HoldingSpaceTray() = default;

void HoldingSpaceTray::Initialize() {
  TrayBackgroundView::Initialize();

  if (features::IsTemporaryHoldingSpacePreviewsEnabled()) {
    DCHECK(previews_tray_icon_);
    UpdatePreviewsVisibility();

    // If previews feature is enabled, the preview icon is displayed
    // conditionally, depending on user prefs state.
    auto* prefs = Shell::Get()->session_controller()->GetActivePrefService();
    if (prefs)
      ObservePrefService(prefs);
  }

  // It's possible that this holding space tray was created after login, such as
  // would occur if the user connects an external display. In such situations
  // the holding space model will already have been attached.
  if (HoldingSpaceController::Get()->model())
    OnHoldingSpaceModelAttached(HoldingSpaceController::Get()->model());
}

void HoldingSpaceTray::ClickedOutsideBubble() {
  CloseBubble();
}

std::u16string HoldingSpaceTray::GetAccessibleNameForTray() {
  return l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_A11Y_NAME);
}

views::View* HoldingSpaceTray::GetTooltipHandlerForPoint(
    const gfx::Point& point) {
  // Tooltip events should be handled top level, not by descendents.
  return HitTestPoint(point) ? this : nullptr;
}

std::u16string HoldingSpaceTray::GetTooltipText(const gfx::Point& point) const {
  return l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_TITLE);
}

void HoldingSpaceTray::HandleLocaleChange() {
  TooltipTextChanged();
}

void HoldingSpaceTray::HideBubbleWithView(const TrayBubbleView* bubble_view) {}

void HoldingSpaceTray::AnchorUpdated() {
  if (bubble_)
    bubble_->AnchorUpdated();
}

void HoldingSpaceTray::UpdateAfterLoginStatusChange() {
  UpdateVisibility();
}

void HoldingSpaceTray::CloseBubble() {
  if (!bubble_)
    return;

  holding_space_metrics::RecordPodAction(
      holding_space_metrics::PodAction::kCloseBubble);

  widget_observer_.Reset();

  bubble_.reset();
  SetIsActive(false);
}

void HoldingSpaceTray::ShowBubble() {
  if (bubble_)
    return;

  holding_space_metrics::RecordPodAction(
      holding_space_metrics::PodAction::kShowBubble);

  DCHECK(tray_container());

  bubble_ = std::make_unique<HoldingSpaceTrayBubble>(this);

  // Observe the bubble widget so that we can do proper clean up when it is
  // being destroyed. If destruction is due to a call to `CloseBubble()` we will
  // have already cleaned up state but there are cases where the bubble widget
  // is destroyed independent of a call to `CloseBubble()`, e.g. ESC key press.
  widget_observer_.Observe(bubble_->GetBubbleWidget());

  SetIsActive(true);
}

TrayBubbleView* HoldingSpaceTray::GetBubbleView() {
  return bubble_ ? bubble_->GetBubbleView() : nullptr;
}

views::Widget* HoldingSpaceTray::GetBubbleWidget() const {
  return bubble_ ? bubble_->GetBubbleWidget() : nullptr;
}

void HoldingSpaceTray::SetVisiblePreferred(bool visible_preferred) {
  if (this->visible_preferred() == visible_preferred)
    return;

  holding_space_metrics::RecordPodAction(
      visible_preferred ? holding_space_metrics::PodAction::kShowPod
                        : holding_space_metrics::PodAction::kHidePod);

  TrayBackgroundView::SetVisiblePreferred(visible_preferred);

  if (!visible_preferred)
    CloseBubble();
}

bool HoldingSpaceTray::GetDropFormats(
    int* formats,
    std::set<ui::ClipboardFormatType>* format_types) {
  *formats = ui::OSExchangeData::FILE_NAME;
  return true;
}

bool HoldingSpaceTray::AreDropTypesRequired() {
  return true;
}

bool HoldingSpaceTray::CanDrop(const ui::OSExchangeData& data) {
  return !ExtractUnpinnedFilePaths(data).empty();
}

// TODO(crbug.com/1171059): Instead of handling `OnDragEntered()`, show the
// `drop_target_overlay_` if the cursor is within range of this view.
void HoldingSpaceTray::OnDragEntered(const ui::DropTargetEvent& event) {
  if (ExtractUnpinnedFilePaths(event.data()).empty())
    UpdateDropTargetState(/*is_drop_target=*/false, &event);
  else
    UpdateDropTargetState(/*is_drop_target=*/true, &event);
}

int HoldingSpaceTray::OnDragUpdated(const ui::DropTargetEvent& event) {
  if (ExtractUnpinnedFilePaths(event.data()).empty()) {
    UpdateDropTargetState(/*is_drop_target=*/false, &event);
    return ui::DragDropTypes::DRAG_NONE;
  }
  UpdateDropTargetState(/*is_drop_target=*/true, &event);
  return ui::DragDropTypes::DRAG_COPY;
}

// TODO(crbug.com/1171059): Instead of handling `OnDragExited()`, hide the
// `drop_target_overlay_` if the cursor is outside range of this view.
void HoldingSpaceTray::OnDragExited() {
  UpdateDropTargetState(/*is_drop_target=*/false, /*event=*/nullptr);
}

DragOperation HoldingSpaceTray::OnPerformDrop(
    const ui::DropTargetEvent& event) {
  UpdateDropTargetState(/*is_drop_target=*/false, /*event=*/nullptr);

  std::vector<base::FilePath> unpinned_file_paths(
      ExtractUnpinnedFilePaths(event.data()));
  if (unpinned_file_paths.empty())
    return DragOperation::kNone;

  holding_space_metrics::RecordPodAction(
      holding_space_metrics::PodAction::kDragAndDropToPin);

  HoldingSpaceController::Get()->client()->PinFiles(unpinned_file_paths);
  return DragOperation::kCopy;
}

void HoldingSpaceTray::Layout() {
  TrayBackgroundView::Layout();

  // The `drop_target_overlay_` should always fill this view's bounds as they
  // are perceived by the user. Note that the user perceives the bounds of this
  // view to be its background bounds, not its local bounds.
  drop_target_overlay_->SetBoundsRect(GetBackgroundBounds());
}

void HoldingSpaceTray::FirePreviewsUpdateTimerIfRunningForTesting() {
  if (previews_update_.IsRunning())
    previews_update_.FireNow();
}

void HoldingSpaceTray::UpdateVisibility() {
  HoldingSpaceModel* const model = HoldingSpaceController::Get()->model();
  if (!model || Shell::Get()->session_controller()->IsUserSessionBlocked()) {
    SetVisiblePreferred(false);
    return;
  }

  PrefService* prefs =
      Shell::Get()->session_controller()->GetActivePrefService();
  const bool has_ever_added_item =
      prefs ? holding_space_prefs::GetTimeOfFirstAdd(prefs).has_value() : false;
  const bool has_ever_pinned_item =
      prefs ? holding_space_prefs::GetTimeOfFirstPin(prefs).has_value() : false;

  // The holding space tray should not be visible in the shelf until the user
  // has added their first item to holding space. Once an item has been added,
  // the holding space tray will continue to be visible until the user has
  // pinned their first file. After the user has pinned their first file, the
  // holding space tray will only be visible in the shelf if their holding space
  // contains finalized items.
  SetVisiblePreferred((has_ever_added_item && !has_ever_pinned_item) ||
                      ModelContainsFinalizedItems(model));
}

std::u16string HoldingSpaceTray::GetAccessibleNameForBubble() {
  return GetAccessibleNameForTray();
}

bool HoldingSpaceTray::ShouldEnableExtraKeyboardAccessibility() {
  return Shell::Get()->accessibility_controller()->spoken_feedback().enabled();
}

void HoldingSpaceTray::HideBubble(const TrayBubbleView* bubble_view) {
  CloseBubble();
}

void HoldingSpaceTray::OnHoldingSpaceModelAttached(HoldingSpaceModel* model) {
  model_observer_.Observe(model);
  UpdateVisibility();
  UpdatePreviewsState();
}

void HoldingSpaceTray::OnHoldingSpaceModelDetached(HoldingSpaceModel* model) {
  model_observer_.Reset();
  UpdateVisibility();
  UpdatePreviewsState();
}

void HoldingSpaceTray::OnHoldingSpaceItemsAdded(
    const std::vector<const HoldingSpaceItem*>& items) {
  UpdateVisibility();
  UpdatePreviewsState();
}

void HoldingSpaceTray::OnHoldingSpaceItemsRemoved(
    const std::vector<const HoldingSpaceItem*>& items) {
  UpdateVisibility();
  UpdatePreviewsState();
}

void HoldingSpaceTray::OnHoldingSpaceItemFinalized(
    const HoldingSpaceItem* item) {
  UpdateVisibility();
  UpdatePreviewsState();
}

void HoldingSpaceTray::ExecuteCommand(int command_id, int event_flags) {
  DCHECK(features::IsTemporaryHoldingSpacePreviewsEnabled());
  switch (static_cast<HoldingSpaceCommandId>(command_id)) {
    case HoldingSpaceCommandId::kHidePreviews:
      holding_space_metrics::RecordPodAction(
          holding_space_metrics::PodAction::kHidePreviews);

      holding_space_prefs::SetPreviewsEnabled(
          Shell::Get()->session_controller()->GetActivePrefService(), false);
      break;
    case HoldingSpaceCommandId::kShowPreviews:
      holding_space_metrics::RecordPodAction(
          holding_space_metrics::PodAction::kShowPreviews);

      holding_space_prefs::SetPreviewsEnabled(
          Shell::Get()->session_controller()->GetActivePrefService(), true);
      break;
    default:
      NOTREACHED();
      break;
  }
}

void HoldingSpaceTray::ShowContextMenuForViewImpl(
    views::View* source,
    const gfx::Point& point,
    ui::MenuSourceType source_type) {
  DCHECK(features::IsTemporaryHoldingSpacePreviewsEnabled());

  holding_space_metrics::RecordPodAction(
      holding_space_metrics::PodAction::kShowContextMenu);

  context_menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);

  const bool previews_enabled = holding_space_prefs::IsPreviewsEnabled(
      Shell::Get()->session_controller()->GetActivePrefService());

  if (previews_enabled) {
    context_menu_model_->AddItemWithIcon(
        static_cast<int>(HoldingSpaceCommandId::kHidePreviews),
        l10n_util::GetStringUTF16(
            IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_HIDE_PREVIEWS),
        ui::ImageModel::FromVectorIcon(kVisibilityOffIcon, /*color_id=*/-1,
                                       kHoldingSpaceIconSize));
  } else {
    context_menu_model_->AddItemWithIcon(
        static_cast<int>(HoldingSpaceCommandId::kShowPreviews),
        l10n_util::GetStringUTF16(
            IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_PREVIEWS),
        ui::ImageModel::FromVectorIcon(kVisibilityIcon, /*color_id=*/-1,
                                       kHoldingSpaceIconSize));
  }

  const int run_types = views::MenuRunner::USE_TOUCHABLE_LAYOUT |
                        views::MenuRunner::CONTEXT_MENU |
                        views::MenuRunner::FIXED_ANCHOR;

  context_menu_runner_ =
      std::make_unique<views::MenuRunner>(context_menu_model_.get(), run_types);

  gfx::Rect anchor = source->GetBoundsInScreen();
  anchor.Inset(gfx::Insets(-kHoldingSpaceContextMenuMargin, 0));

  context_menu_runner_->RunMenuAt(
      source->GetWidget(), /*button_controller=*/nullptr, anchor,
      views::MenuAnchorPosition::kTopLeft, source_type);
}

void HoldingSpaceTray::OnWidgetDragWillStart(views::Widget* widget) {
  // The holding space bubble should be closed while dragging holding space
  // items so as not to obstruct drop targets. Post the task to close the bubble
  // so that we don't attempt to destroy the bubble widget before the associated
  // drag event has been fully initialized.
  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&HoldingSpaceTray::CloseBubble,
                                weak_factory_.GetWeakPtr()));
}

void HoldingSpaceTray::OnWidgetDestroying(views::Widget* widget) {
  CloseBubble();
}

void HoldingSpaceTray::OnActiveUserPrefServiceChanged(PrefService* prefs) {
  if (!features::IsTemporaryHoldingSpacePreviewsEnabled())
    return;

  UpdatePreviewsState();
  ObservePrefService(prefs);
}

void HoldingSpaceTray::OnSessionStateChanged(
    session_manager::SessionState state) {
  UpdateVisibility();
}

void HoldingSpaceTray::ObservePrefService(PrefService* prefs) {
  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  pref_change_registrar_->Init(prefs);

  // NOTE: The callback being bound is scoped to `pref_change_registrar_` which
  // is owned by `this` so it is safe to bind with an unretained raw pointer.
  holding_space_prefs::AddPreviewsEnabledChangedCallback(
      pref_change_registrar_.get(),
      base::BindRepeating(&HoldingSpaceTray::UpdatePreviewsState,
                          base::Unretained(this)));
}

void HoldingSpaceTray::UpdatePreviewsState() {
  UpdatePreviewsVisibility();
  SchedulePreviewsIconUpdate();
}

void HoldingSpaceTray::UpdatePreviewsVisibility() {
  const bool show_previews =
      IsPreviewsEnabled() && HoldingSpaceController::Get()->model() &&
      ModelContainsFinalizedItems(HoldingSpaceController::Get()->model());

  if (PreviewsShown() == show_previews)
    return;
  default_tray_icon_->SetVisible(!show_previews);

  DCHECK(previews_tray_icon_);
  previews_tray_icon_->SetVisible(show_previews);

  if (!show_previews) {
    previews_tray_icon_->Clear();
    previews_update_.Stop();
  }
}

void HoldingSpaceTray::SchedulePreviewsIconUpdate() {
  if (previews_update_.IsRunning())
    return;

  // Schedule async task with a short (somewhat arbitrary) delay to update
  // previews so items added in quick succession are handled together.
  base::TimeDelta delay = use_zero_previews_update_delay_
                              ? base::TimeDelta()
                              : base::TimeDelta::FromMilliseconds(50);
  previews_update_.Start(FROM_HERE, delay,
                         base::BindOnce(&HoldingSpaceTray::UpdatePreviewsIcon,
                                        base::Unretained(this)));
}

void HoldingSpaceTray::UpdatePreviewsIcon() {
  if (!PreviewsShown()) {
    if (previews_tray_icon_)
      previews_tray_icon_->Clear();
    return;
  }

  std::vector<const HoldingSpaceItem*> items_with_previews;
  std::set<base::FilePath> paths_with_previews;
  for (const auto& item :
       base::Reversed(HoldingSpaceController::Get()->model()->items())) {
    if (!item->IsFinalized())
      continue;
    if (base::Contains(paths_with_previews, item->file_path()))
      continue;
    items_with_previews.push_back(item.get());
    paths_with_previews.insert(item->file_path());
  }
  previews_tray_icon_->UpdatePreviews(items_with_previews);
}

bool HoldingSpaceTray::PreviewsShown() const {
  return previews_tray_icon_ && previews_tray_icon_->GetVisible();
}

// TODO(crbug.com/1171059): Animate translation of tray icons.
void HoldingSpaceTray::UpdateDropTargetState(bool is_drop_target,
                                             const ui::LocatedEvent* event) {
  AnimateToTargetOpacity(drop_target_overlay_, is_drop_target ? 1.f : 0.f);
  AnimateToTargetOpacity(default_tray_icon_, is_drop_target ? 0.f : 1.f);
  AnimateToTargetOpacity(previews_tray_icon_, is_drop_target ? 0.f : 1.f);

  const views::InkDropState target_ink_drop_state =
      is_drop_target ? views::InkDropState::ACTION_PENDING
                     : views::InkDropState::HIDDEN;
  if (GetInkDrop()->GetTargetInkDropState() == target_ink_drop_state)
    return;

  // Even though `event` is a `ui::LocatedEvent`, it may *not* return `true` for
  // `IsLocatedEvent()` which is checked downstream when animating the ink drop.
  // Since the only data that needs to propagate is `event` location, create a
  // synthetic event that *will* return `true` for `IsLocatedEvent()` if needed.
  std::unique_ptr<ui::MouseEvent> mouse_moved_event;
  if (event && !event->IsLocatedEvent()) {
    mouse_moved_event = std::make_unique<ui::MouseEvent>(
        ui::ET_MOUSE_MOVED, event->location_f(), event->root_location_f(),
        event->time_stamp(), /*flags=*/ui::EF_NONE,
        /*changed_button_flags=*/ui::EF_NONE);
    event = mouse_moved_event.get();
  }

  AnimateInkDrop(target_ink_drop_state, event);
}

BEGIN_METADATA(HoldingSpaceTray, TrayBackgroundView)
END_METADATA

}  // namespace ash
