// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/events/event_source.h"

#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/event_rewriter_continuation.h"
#include "ui/events/event_sink.h"

namespace ui {

namespace {

bool IsLocatedEventWithDifferentLocations(const Event& event) {
  if (!event.IsLocatedEvent())
    return false;
  const LocatedEvent* located_event = event.AsLocatedEvent();
  return located_event->target() &&
         located_event->location_f() != located_event->root_location_f();
}

}  // namespace

class EventSource::EventRewriterContinuationImpl
    : public EventRewriterContinuation {
 public:
  // Constructs an EventRewriterContinuationImpl at the end of the source's
  // rewriter list.
  static void Create(EventSource* const source, EventRewriter* rewriter) {
    DCHECK(source);
    DCHECK(rewriter);
    DCHECK(source->FindContinuation(rewriter) == source->rewriter_list_.end());
    source->rewriter_list_.push_back(
        std::make_unique<EventRewriterContinuationImpl>(source, rewriter));
    EventRewriterList::iterator it = source->rewriter_list_.end();
    --it;
    CHECK((*it)->rewriter() == rewriter);
    (*it)->self_ = it;
  }

  EventRewriterContinuationImpl(EventSource* const source,
                                EventRewriter* rewriter)
      : source_(source),
        rewriter_(rewriter),
        self_(source->rewriter_list_.end()) {}

  EventRewriterContinuationImpl(const EventRewriterContinuationImpl&) = delete;
  EventRewriterContinuationImpl& operator=(
      const EventRewriterContinuationImpl&) = delete;

  ~EventRewriterContinuationImpl() override {}

  EventRewriter* rewriter() const { return rewriter_; }

  base::WeakPtr<EventRewriterContinuationImpl> GetWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

  // EventRewriterContinuation overrides:
  EventDispatchDetails SendEvent(const Event* event) override {
    EventRewriterList::iterator next = self_;
    ++next;
    if (next == source_->rewriter_list_.end())
      return SendEventFinally(event);
    return (*next)->rewriter_->RewriteEvent(*event, (*next)->GetWeakPtr());
  }

  EventDispatchDetails SendEventFinally(const Event* event) override {
    return source_->DeliverEventToSink(const_cast<Event*>(event));
  }

  EventDispatchDetails DiscardEvent() override {
    ui::EventDispatchDetails details;
    details.event_discarded = true;
    return details;
  }

 private:
  const raw_ptr<EventSource> source_;
  raw_ptr<EventRewriter, DanglingUntriaged> rewriter_;
  EventRewriterList::iterator self_;

  base::WeakPtrFactory<EventRewriterContinuationImpl> weak_ptr_factory_{this};
};

EventSource::EventSource() = default;

EventSource::~EventSource() = default;

void EventSource::AddEventRewriter(EventRewriter* rewriter) {
  EventRewriterContinuationImpl::Create(this, rewriter);
}

void EventSource::RemoveEventRewriter(EventRewriter* rewriter) {
  EventRewriterList::iterator it = FindContinuation(rewriter);
  if (it == rewriter_list_.end()) {
    // We need to tolerate attempting to remove an unregistered
    // EventRewriter, because many unit tests currently do so:
    // the rewriter gets added to the current root window source
    // on construction, and removed from the current root window
    // source on destruction, but the root window changes in
    // between.
    LOG(WARNING) << "EventRewriter not registered";
    return;
  }
  rewriter_list_.erase(it);
}

EventDispatchDetails EventSource::SendEventToSink(const Event* event) {
  return SendEventToSinkFromRewriter(event, nullptr);
}

EventDispatchDetails EventSource::DeliverEventToSink(Event* event) {
  EventSink* sink = GetEventSink();
  CHECK(sink);
  return sink->OnEventFromSource(event);
}

EventDispatchDetails EventSource::SendEventToSinkFromRewriter(
    const Event* event,
    const EventRewriter* rewriter) {
  std::unique_ptr<Event> event_clone;
  EventRewriterList::iterator it = rewriter_list_.begin();
  if (rewriter) {
    // If a rewriter reposted |event|, only send it to subsequent rewriters.
    it = FindContinuation(rewriter);
    CHECK(it != rewriter_list_.end());
    ++it;
  }
  if (it == rewriter_list_.end()) {
    return DeliverEventToSink(const_cast<Event*>(event));
  }

  const Event* event_for_rewriting = event;
  EventRewriterContinuationImpl* const next = it->get();
  // Historically, EventRewriters are not expected to honor the event target.
  // Though, due to observed crashes (see https://crbug.com/1347192), rewriters
  // are being refactored to honor it. Thus, unless the next rewriter supports
  // such behavior, event location must be equal to its root_location and target
  // unset, which is not copied by Event::Clone() call below.
  if (IsLocatedEventWithDifferentLocations(*event) &&
      !next->rewriter()->SupportsNonRootLocation()) {
    event_clone = event->Clone();
    event_clone->AsLocatedEvent()->set_location_f(
        event_clone->AsLocatedEvent()->root_location_f());
    event_for_rewriting = event_clone.get();
  }
  return next->rewriter()->RewriteEvent(*event_for_rewriting,
                                        next->GetWeakPtr());
}

EventSource::EventRewriterList::iterator EventSource::FindContinuation(
    const EventRewriter* rewriter) {
  auto it = find_if(
      rewriter_list_.begin(), rewriter_list_.end(),
      [rewriter](const std::unique_ptr<EventRewriterContinuationImpl>& p)
          -> bool { return p->rewriter() == rewriter; });
  return it;
}

}  // namespace ui
