// Copyright 2019 The Fuchsia 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 <fuchsia/ui/input/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>

#include <gtest/gtest.h>

#include "src/lib/ui/input/gesture_detector.h"

namespace {

using fuchsia::ui::input::PointerEvent;
using fuchsia::ui::input::PointerEventPhase;
using fuchsia::ui::input::PointerEventType;

enum class InteractionType { kUnknown, kPreTap, kTap, kDrag };

struct InteractionRecord {
  bool active = false;
  InteractionType interaction_type = InteractionType::kUnknown;
  input::GestureDetector::TapType tap_type;
  glm::vec2 coordinate;
  input::Gesture::Delta delta;
};

class TestInteraction : public input::GestureDetector::Interaction {
 public:
  TestInteraction(InteractionRecord* record) : record_(record) { *record_ = {.active = true}; }

  ~TestInteraction() override { record_->active = false; }

 private:
  void OnTapBegin(const glm::vec2& coordinate, input::GestureDetector::TapType tap_type) override {
    EXPECT_EQ(record_->interaction_type, InteractionType::kUnknown);
    record_->interaction_type = InteractionType::kPreTap;
    record_->coordinate = coordinate;
    record_->tap_type = tap_type;
  }

  void OnTapUpdate(input::GestureDetector::TapType tap_type) override {
    EXPECT_EQ(record_->interaction_type, InteractionType::kPreTap);
    record_->tap_type = tap_type;
  }

  void OnTapCommit() override {
    EXPECT_EQ(record_->interaction_type, InteractionType::kPreTap);
    record_->interaction_type = InteractionType::kTap;
  }

  void OnMultidrag(input::GestureDetector::TapType tap_type,
                   const input::Gesture::Delta& delta) override {
    record_->interaction_type = InteractionType::kDrag;
    record_->tap_type = tap_type;
    record_->delta += delta;
  }

  InteractionRecord* record_;
};

class FakeDelegate : public input::GestureDetector::Delegate {
 public:
  void SetNextInteraction(std::unique_ptr<input::GestureDetector::Interaction> next_interaction) {
    next_interaction_ = std::move(next_interaction);
  }

 private:
  // |input::GestureDetector::Delegate|
  std::unique_ptr<input::GestureDetector::Interaction> BeginInteraction(
      const input::Gesture* gesture) override {
    EXPECT_TRUE(next_interaction_) << "Unexpected BeginInteraction";
    return std::move(next_interaction_);
  }

  std::unique_ptr<input::GestureDetector::Interaction> next_interaction_;
};

class GestureDetectorTest : public testing::Test {
 public:
  GestureDetectorTest() : gesture_detector_(&delegate_) {}

 protected:
  // Sets up a |TestInteraction| to be the next |Interaction| returned by
  // |BeginInteraction|.
  void RecordInteraction(InteractionRecord* record) {
    delegate_.SetNextInteraction(std::make_unique<TestInteraction>(record));
  }

  input::GestureDetector* gesture_detector() { return &gesture_detector_; }

 private:
  FakeDelegate delegate_;
  input::GestureDetector gesture_detector_;
};

TEST_F(GestureDetectorTest, IgnoreMouseHover) {
  PointerEvent mouse = {.device_id = 0,
                        .pointer_id = 0,
                        .type = PointerEventType::MOUSE,
                        .phase = PointerEventPhase::MOVE,
                        .x = 0,
                        .y = 0};

  // If we erroneously create a new interaction at any point, this will violate
  // the expectation in |GestureDetectorTest::BeginInteraction|.

  gesture_detector()->OnPointerEvent(mouse);

  // Move the pointer around past the drag threshold.
  mouse.x += 2 * input::GestureDetector::kDefaultDragThreshold;
  gesture_detector()->OnPointerEvent(mouse);
}

// A default starting point for touch events. Usages should explicitly set any
// members (other than |.type|) that they care about.
constexpr PointerEvent kDefaultTouchEvent = {
    .device_id = 0, .pointer_id = 0, .type = PointerEventType::TOUCH};

TEST_F(GestureDetectorTest, Tap) {
  InteractionRecord ixn;
  RecordInteraction(&ixn);

  auto ptr = kDefaultTouchEvent;
  ptr.x = 0;
  ptr.y = 0;
  ptr.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr);
  EXPECT_TRUE(ixn.active);

  ptr.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr);
  EXPECT_FALSE(ixn.active);
  // The interaction ends when the last pointer comes up.

  EXPECT_EQ(ixn.interaction_type, InteractionType::kTap);
  EXPECT_EQ(ixn.tap_type, 1);
  EXPECT_EQ(ixn.coordinate, glm::vec2(0, 0));
}

TEST_F(GestureDetectorTest, TwoFingerTap) {
  InteractionRecord ixn;
  RecordInteraction(&ixn);

  auto ptr0 = kDefaultTouchEvent;
  ptr0.pointer_id = 0;
  ptr0.x = 0;
  ptr0.y = 0;
  ptr0.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr0);

  auto ptr1 = kDefaultTouchEvent;
  ptr1.pointer_id = 1;
  ptr1.x = 1;
  ptr1.y = 0;
  ptr1.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr1);

  ptr1.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr1);

  EXPECT_TRUE(ixn.active);
  ptr0.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr0);
  EXPECT_FALSE(ixn.active);

  EXPECT_EQ(ixn.interaction_type, InteractionType::kTap);
  EXPECT_EQ(ixn.tap_type, 2);
  EXPECT_EQ(ixn.coordinate, glm::vec2(0, 0));
}

TEST_F(GestureDetectorTest, TwoFingerTapWithDrift) {
  FX_CHECK(1 < input::GestureDetector::kDefaultDragThreshold)
      << "kDefaultDragThreshold is too low; rewrite this test to override.";

  InteractionRecord ixn;
  RecordInteraction(&ixn);

  auto ptr0 = kDefaultTouchEvent;
  ptr0.pointer_id = 0;
  ptr0.x = 0;
  ptr0.y = 0;
  ptr0.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr0);

  ptr0.x++;
  ptr0.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr0);

  auto ptr1 = kDefaultTouchEvent;
  ptr1.pointer_id = 1;
  ptr1.x = 10;
  ptr1.y = 0;
  ptr1.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr1);

  ptr1.x++;
  ptr1.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr1);

  ptr0.x--;
  gesture_detector()->OnPointerEvent(ptr0);

  // The tap should end after a pointer comes up...
  ptr0.x++;
  ptr0.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr0);
  EXPECT_TRUE(ixn.active);

  // ...after which further movement within the drag threshold should not
  // trigger a drag or a new interaction.
  ptr1.x--;
  gesture_detector()->OnPointerEvent(ptr1);

  EXPECT_TRUE(ixn.active);
  ptr1.x++;
  ptr1.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr1);
  EXPECT_FALSE(ixn.active);

  EXPECT_EQ(ixn.interaction_type, InteractionType::kTap);
  EXPECT_EQ(ixn.tap_type, 2);
  EXPECT_EQ(ixn.coordinate, glm::vec2(0, 0));
}

TEST_F(GestureDetectorTest, Drag) {
  InteractionRecord ixn;
  RecordInteraction(&ixn);

  auto ptr0 = kDefaultTouchEvent;
  ptr0.pointer_id = 0;
  ptr0.x = 0;
  ptr0.y = 0;
  ptr0.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr0);

  ptr0.x += input::GestureDetector::kDefaultDragThreshold;
  ptr0.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr0);

  EXPECT_EQ(ixn.interaction_type, InteractionType::kDrag);
  EXPECT_EQ(ixn.tap_type, 1);
  EXPECT_EQ(ixn.delta, input::Gesture::Delta(
                           {.translation = {input::GestureDetector::kDefaultDragThreshold, 0},
                            .rotation = 0,
                            .scale = 1}));

  auto ptr1 = kDefaultTouchEvent;
  ptr1.pointer_id = 1;
  ptr1.x = 0;
  ptr1.y = 10;
  ptr1.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr1);

  EXPECT_EQ(ixn.tap_type, 2);

  ptr1.x++;
  ptr1.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr1);

  EXPECT_GT(ixn.delta.translation.x, input::GestureDetector::kDefaultDragThreshold);

  ptr0.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr0);

  EXPECT_EQ(ixn.tap_type, 1);
}

// This covers the case where a tap has been committed due to a pointer release
// but the remaining pointer is dragged past the threshold.
TEST_F(GestureDetectorTest, TapIntoDrag) {
  const float dx = 2 * input::GestureDetector::kDefaultDragThreshold;

  InteractionRecord ixn;
  RecordInteraction(&ixn);

  auto ptr0 = kDefaultTouchEvent;
  ptr0.pointer_id = 0;
  ptr0.x = 0;
  ptr0.y = 0;
  ptr0.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr0);

  auto ptr1 = kDefaultTouchEvent;
  ptr1.pointer_id = 1;
  ptr1.x = 0;
  ptr1.y = 10;
  ptr1.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr1);

  ptr1.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr1);

  EXPECT_EQ(ixn.interaction_type, InteractionType::kTap);

  ptr0.x += dx;
  ptr0.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr0);

  EXPECT_EQ(ixn.interaction_type, InteractionType::kDrag);
  EXPECT_EQ(ixn.tap_type, 1);
  EXPECT_EQ(ixn.delta, input::Gesture::Delta({.translation = {dx, 0}, .rotation = 0, .scale = 1}));
}

// An |input::GestureDetector::Interaction| that owns and destroys its gesture detector on command,
// for testing lifecycle robustness. It's fragile to assume that an interaction will never destroy
// or |Reset()| its gesture detector on a callback.
class PoisonInteraction : public input::GestureDetector::Interaction {
 public:
  PoisonInteraction(std::unique_ptr<input::GestureDetector> gesture_detector)
      : gesture_detector_(std::move(gesture_detector)) {}

  // Sets the gesture detector to self destruct on the next event.
  void Poison() { poisoned_ = true; }

 private:
  void OnTapBegin(const glm::vec2&, input::GestureDetector::TapType) override { CheckPoison(); }

  void OnTapUpdate(input::GestureDetector::TapType) override { CheckPoison(); }

  void OnTapCommit() override { CheckPoison(); }

  void OnMultidrag(input::GestureDetector::TapType, const input::Gesture::Delta&) override {
    CheckPoison();
  }

  void CheckPoison() {
    if (poisoned_) {
      gesture_detector_ = nullptr;
    }
  }

  bool poisoned_ = false;
  std::unique_ptr<input::GestureDetector> gesture_detector_;
};

// These tests won't necessarily fail if the code is incorrect as referencing released memory is
// undefined behavior, but the allocator does catch some cases.
class PoisonInteractionTest : public testing::Test {
 public:
  PoisonInteractionTest() {
    auto gesture_detector = std::make_unique<input::GestureDetector>(&delegate);
    gesture_detector_ = gesture_detector.get();
    auto interaction = std::make_unique<PoisonInteraction>(std::move(gesture_detector));
    interaction_ = interaction.get();
    delegate.SetNextInteraction(std::move(interaction));
  }

  input::GestureDetector* gesture_detector() { return gesture_detector_; }
  PoisonInteraction* interaction() { return interaction_; }

 private:
  FakeDelegate delegate;
  input::GestureDetector* gesture_detector_;
  PoisonInteraction* interaction_;
};

TEST_F(PoisonInteractionTest, PoisonTapBegin) {
  interaction()->Poison();

  auto ptr = kDefaultTouchEvent;
  ptr.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr);
}

TEST_F(PoisonInteractionTest, PoisonTapUpdate) {
  auto ptr0 = kDefaultTouchEvent;
  ptr0.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr0);

  interaction()->Poison();
  auto ptr1 = kDefaultTouchEvent;
  ptr1.pointer_id = 1;
  ptr1.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr1);
}

TEST_F(PoisonInteractionTest, PoisonTapCommit) {
  auto ptr = kDefaultTouchEvent;
  ptr.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr);

  interaction()->Poison();
  ptr.phase = PointerEventPhase::UP;
  gesture_detector()->OnPointerEvent(ptr);
}

TEST_F(PoisonInteractionTest, PoisonMultidrag) {
  auto ptr = kDefaultTouchEvent;
  ptr.x = 0;
  ptr.y = 0;
  ptr.phase = PointerEventPhase::DOWN;
  gesture_detector()->OnPointerEvent(ptr);

  interaction()->Poison();
  ptr.x += input::GestureDetector::kDefaultDragThreshold;
  ptr.phase = PointerEventPhase::MOVE;
  gesture_detector()->OnPointerEvent(ptr);
}

class PoisonDelegate : public input::GestureDetector::Delegate {
 public:
  void SetGestureDetector(std::unique_ptr<input::GestureDetector> gesture_detector) {
    gesture_detector_ = std::move(gesture_detector);
  }

  input::GestureDetector* gesture_detector() { return gesture_detector_.get(); }

 private:
  // |input::GestureDetector::Delegate|
  std::unique_ptr<input::GestureDetector::Interaction> BeginInteraction(
      const input::Gesture* gesture) override {
    gesture_detector_ = nullptr;
    return nullptr;
  }

  std::unique_ptr<input::GestureDetector> gesture_detector_;
};

TEST(PoisonDelegateTest, PoisonBeginInteraction) {
  PoisonDelegate delegate;
  delegate.SetGestureDetector(std::make_unique<input::GestureDetector>(&delegate));

  auto ptr = kDefaultTouchEvent;
  ptr.phase = PointerEventPhase::DOWN;
  delegate.gesture_detector()->OnPointerEvent(ptr);
}

}  // namespace
