// Copyright 2017 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 "components/exo/data_device.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/run_loop.h"
#include "build/chromeos_buildflags.h"
#include "components/exo/data_device_delegate.h"
#include "components/exo/data_exchange_delegate.h"
#include "components/exo/data_offer.h"
#include "components/exo/data_source.h"
#include "components/exo/seat.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chromeos/ui/base/window_properties.h"
#include "components/exo/extended_drag_source.h"
#endif

namespace exo {
namespace {

using ::ui::mojom::DragOperation;

constexpr int kDataDeviceSeatObserverPriority = 0;
static_assert(Seat::IsValidObserverPriority(kDataDeviceSeatObserverPriority),
              "kDataDeviceSeatObserverPriority is not in the valid range.");

constexpr base::TimeDelta kDataOfferDestructionTimeout =
    base::Milliseconds(1000);

DragOperation DndActionToDragOperation(DndAction dnd_action) {
  switch (dnd_action) {
    case DndAction::kMove:
      return DragOperation::kMove;
    case DndAction::kCopy:
      return DragOperation::kCopy;
    case DndAction::kAsk:
      return DragOperation::kLink;
    case DndAction::kNone:
      return DragOperation::kNone;
  }
}

}  // namespace

DataDevice::DataDevice(DataDeviceDelegate* delegate, Seat* seat)
    : delegate_(delegate), seat_(seat), drop_succeeded_(false) {
  WMHelper::GetInstance()->AddDragDropObserver(this);
  ui::ClipboardMonitor::GetInstance()->AddObserver(this);

  seat_->AddObserver(this, kDataDeviceSeatObserverPriority);

  OnSurfaceFocused(seat_->GetFocusedSurface(), nullptr,
                   !!seat_->GetFocusedSurface());
}

DataDevice::~DataDevice() {
  delegate_->OnDataDeviceDestroying(this);

  WMHelper::GetInstance()->RemoveDragDropObserver(this);
  ui::ClipboardMonitor::GetInstance()->RemoveObserver(this);

  seat_->RemoveObserver(this);
}

void DataDevice::StartDrag(DataSource* source,
                           Surface* origin,
                           Surface* icon,
                           ui::mojom::DragEventSource event_source) {
  seat_->StartDrag(source, origin, icon, event_source);
}

void DataDevice::SetSelection(DataSource* source) {
  seat_->SetSelection(source);
}

void DataDevice::OnDragEntered(const ui::DropTargetEvent& event) {
  DCHECK(!data_offer_);

  Surface* surface = GetEffectiveTargetForEvent(event);
  if (!surface)
    return;

  base::flat_set<DndAction> dnd_actions;
  if (event.source_operations() & ui::DragDropTypes::DRAG_MOVE) {
    dnd_actions.insert(DndAction::kMove);
  }
  if (event.source_operations() & ui::DragDropTypes::DRAG_COPY) {
    dnd_actions.insert(DndAction::kCopy);
  }
  if (event.source_operations() & ui::DragDropTypes::DRAG_LINK) {
    dnd_actions.insert(DndAction::kAsk);
  }

  data_offer_ =
      std::make_unique<ScopedDataOffer>(delegate_->OnDataOffer(), this);
  data_offer_->get()->SetDropData(seat_->data_exchange_delegate(),
                                  surface->window(), event.data());
  data_offer_->get()->SetSourceActions(dnd_actions);
  data_offer_->get()->SetActions(base::flat_set<DndAction>(), DndAction::kAsk);
  delegate_->OnEnter(surface, event.location_f(), *data_offer_->get());
}

aura::client::DragUpdateInfo DataDevice::OnDragUpdated(
    const ui::DropTargetEvent& event) {
  if (!data_offer_)
    return aura::client::DragUpdateInfo();

  ui::EndpointType endpoint_type = ui::EndpointType::kDefault;
  Surface* surface = GetEffectiveTargetForEvent(event);
  if (surface) {
    endpoint_type =
        seat_->data_exchange_delegate()->GetDataTransferEndpointType(
            surface->window());
  }
  aura::client::DragUpdateInfo drag_info(
      ui::DragDropTypes::DRAG_NONE, ui::DataTransferEndpoint(endpoint_type));

  bool prevent_motion_drag_events = false;

#if BUILDFLAG(IS_CHROMEOS_ASH)
  // chromeos::kCanAttachToAnotherWindowKey controls if a drag operation should
  // trigger swallow/unswallow tab.
  if (focused_surface_) {
    // The ExtendedDragSource instance can be null for tests.
    auto* extended_drag_source = ExtendedDragSource::Get();
    bool is_extended_drag_source_active =
        extended_drag_source && extended_drag_source->IsActive();

    prevent_motion_drag_events =
        is_extended_drag_source_active &&
        !focused_surface_->get()->window()->GetToplevelWindow()->GetProperty(
            chromeos::kCanAttachToAnotherWindowKey);
  }
#endif

  if (!prevent_motion_drag_events)
    delegate_->OnMotion(event.time_stamp(), event.location_f());

  // TODO(hirono): dnd_action() here may not be updated. Chrome needs to provide
  // a way to update DND action asynchronously.
  drag_info.drag_operation = static_cast<int>(
      DndActionToDragOperation(data_offer_->get()->dnd_action()));
  return drag_info;
}

void DataDevice::OnDragExited() {
  if (!data_offer_)
    return;

  delegate_->OnLeave();
  data_offer_.reset();
}

WMHelper::DragDropObserver::DropCallback DataDevice::GetDropCallback() {
  base::ScopedClosureRunner drag_exit(
      base::BindOnce(&DataDevice::OnDragExited, weak_factory_.GetWeakPtr()));
  return base::BindOnce(&DataDevice::PerformDropOrExitDrag,
                        drop_weak_factory_.GetWeakPtr(), std::move(drag_exit));
}

void DataDevice::OnClipboardDataChanged() {
  if (!focused_surface_)
    return;
  SetSelectionToCurrentClipboardData();
}

void DataDevice::OnSurfaceFocused(Surface* gained_surface,
                                  Surface* lost_focused,
                                  bool has_focused_surface) {
  Surface* next_focused_surface =
      gained_surface && delegate_->CanAcceptDataEventsForSurface(gained_surface)
          ? gained_surface
          : nullptr;
  // Check if focused surface is not changed.
  if (focused_surface_ && focused_surface_->get() == next_focused_surface)
    return;

  std::unique_ptr<ScopedSurface> last_focused_surface =
      std::move(focused_surface_);
  focused_surface_ = next_focused_surface ? std::make_unique<ScopedSurface>(
                                                next_focused_surface, this)
                                          : nullptr;

  // Check if the client newly obtained focus.
  if (focused_surface_ && !last_focused_surface)
    SetSelectionToCurrentClipboardData();
}

void DataDevice::OnDataOfferDestroying(DataOffer* data_offer) {
  if (data_offer_ && data_offer_->get() == data_offer) {
    drop_succeeded_ = data_offer_->get()->finished();
    if (quit_closure_)
      std::move(quit_closure_).Run();
    data_offer_.reset();
  }
  drop_weak_factory_.InvalidateWeakPtrs();
}

void DataDevice::OnSurfaceDestroying(Surface* surface) {
  if (focused_surface_ && focused_surface_->get() == surface)
    focused_surface_.reset();
}

Surface* DataDevice::GetEffectiveTargetForEvent(
    const ui::DropTargetEvent& event) const {
  aura::Window* window = static_cast<aura::Window*>(event.target());
  if (!window)
    return nullptr;
  Surface* target = Surface::AsSurface(window);
  if (!target)
    return nullptr;

  return delegate_->CanAcceptDataEventsForSurface(target) ? target : nullptr;
}

void DataDevice::SetSelectionToCurrentClipboardData() {
  DCHECK(focused_surface_);
  DataOffer* data_offer = delegate_->OnDataOffer();
  data_offer->SetClipboardData(
      seat_->data_exchange_delegate(), *ui::Clipboard::GetForCurrentThread(),
      seat_->data_exchange_delegate()->GetDataTransferEndpointType(
          focused_surface_->get()->window()));
  delegate_->OnSelection(*data_offer);
}

void DataDevice::PerformDropOrExitDrag(
    base::ScopedClosureRunner exit_drag,
    ui::mojom::DragOperation& output_drag_op) {
  exit_drag.ReplaceClosure(base::DoNothing());

  if (!data_offer_) {
    output_drag_op = DragOperation::kNone;
    return;
  }

  DndAction dnd_action = data_offer_->get()->dnd_action();

  delegate_->OnDrop();

  // TODO(crbug.com/1160925): Avoid using nested loop by adding asynchronous
  // callback to aura::client::DragDropDelegate.
  base::WeakPtr<DataDevice> alive(weak_factory_.GetWeakPtr());
  base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), kDataOfferDestructionTimeout);
  quit_closure_ = run_loop.QuitClosure();
  run_loop.Run();

  if (!alive) {
    output_drag_op = DragOperation::kNone;
    return;
  }

  if (quit_closure_) {
    // DataOffer not destroyed by the client until the timeout.
    quit_closure_.Reset();
    data_offer_.reset();
    drop_succeeded_ = false;
  }

  if (!drop_succeeded_)
    output_drag_op = DragOperation::kNone;
  else
    output_drag_op = DndActionToDragOperation(dnd_action);
}

}  // namespace exo
