#include <android/input.h>
#include <gtest/gtest.h>
#include <linux/input.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include "EvdevInjector.h"
#include "VirtualTouchpadEvdev.h"

namespace android {
namespace dvr {

namespace {

class UInputForTesting : public EvdevInjector::UInput {
 public:
  ~UInputForTesting() override {}
  void WriteInputEvent(uint16_t type, uint16_t code, int32_t value) {
    struct input_event event;
    memset(&event, 0, sizeof(event));
    event.type = type;
    event.code = code;
    event.value = value;
    Write(&event, sizeof(event));
  }
};

// Recording test implementation of UInput.
//
class UInputRecorder : public UInputForTesting {
 public:
  UInputRecorder() {}
  ~UInputRecorder() override {}

  const std::string& GetString() const { return s_; }
  void Reset() { s_.clear(); }

  // UInput overrides:

  int Open() override {
    s_ += "o;";
    return 0;
  }

  int Close() override {
    s_ += "c;";
    return 0;
  }

  int Write(const void* buf, size_t count) override {
    s_ += "w(";
    s_ += Encode(&count, sizeof(count));
    s_ += ",";
    s_ += Encode(buf, count);
    s_ += ");";
    return 0;
  }

  int IoctlVoid(int request) override {
    s_ += "i(";
    s_ += Encode(&request, sizeof(request));
    s_ += ");";
    return 0;
  }

  int IoctlSetInt(int request, int value) override {
    s_ += "i(";
    s_ += Encode(&request, sizeof(request));
    s_ += ",";
    s_ += Encode(&value, sizeof(value));
    s_ += ");";
    return 0;
  }

 private:
  std::string s_;

  std::string Encode(const void* buf, size_t count) {
    const char* in = static_cast<const char*>(buf);
    char out[2 * count + 1];
    for (size_t i = 0; i < count; ++i) {
      snprintf(&out[2 * i], 3, "%02X", in[i]);
    }
    return out;
  }
};

class EvdevInjectorForTesting : public EvdevInjector {
 public:
  EvdevInjectorForTesting() { SetUInputForTesting(&record); }
  const uinput_user_dev* GetUiDev() const { return GetUiDevForTesting(); }
  UInputRecorder record;
};

class VirtualTouchpadForTesting : public VirtualTouchpadEvdev {
 public:
  static std::unique_ptr<VirtualTouchpad> Create() {
    return std::unique_ptr<VirtualTouchpad>(New());
  }
  static VirtualTouchpadForTesting* New() {
    VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting();
    touchpad->Reset();
    for (int t = 0; t < kTouchpads; ++t) {
      touchpad->SetEvdevInjectorForTesting(t, &touchpad->injector[t]);
    }
    return touchpad;
  }
  int GetTouchpadCount() const { return kTouchpads; }
  EvdevInjectorForTesting injector[kTouchpads];
};

void DumpDifference(const char* expect, const char* actual) {
  printf("  common: ");
  while (*expect && *expect == *actual) {
    putchar(*expect);
    ++expect;
    ++actual;
  }
  printf("\n  expect: %s\n", expect);
  printf("  actual: %s\n", actual);
}

}  // anonymous namespace

class VirtualTouchpadTest : public testing::Test {};

TEST_F(VirtualTouchpadTest, Goodness) {
  std::unique_ptr<VirtualTouchpadForTesting> touchpad(
      VirtualTouchpadForTesting::New());
  UInputRecorder expect;

  status_t touch_status = touchpad->Attach();
  EXPECT_EQ(0, touch_status);

  // Check some aspects of uinput_user_dev.
  const uinput_user_dev* uidev;
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    uidev = touchpad->injector[t].GetUiDev();
    String8 name;
    name.appendFormat("vr-virtual-touchpad-%d", t);
    EXPECT_EQ(name, uidev->name);
    for (int i = 0; i < ABS_CNT; ++i) {
      EXPECT_EQ(0, uidev->absmin[i]);
      EXPECT_EQ(0, uidev->absfuzz[i]);
      EXPECT_EQ(0, uidev->absflat[i]);
      if (i != ABS_MT_POSITION_X && i != ABS_MT_POSITION_Y &&
          i != ABS_MT_SLOT) {
        EXPECT_EQ(0, uidev->absmax[i]);
      }
    }
  }
  const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X];
  const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y];
  const int32_t slots = uidev->absmax[ABS_MT_SLOT];

  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    // Check the system calls performed by initialization.
    expect.Reset();
    // From ConfigureBegin():
    expect.Open();
    // From ConfigureInputProperty(INPUT_PROP_DIRECT):
    expect.IoctlSetInt(UI_SET_PROPBIT, INPUT_PROP_DIRECT);
    // From ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1):
    expect.IoctlSetInt(UI_SET_EVBIT, EV_ABS);
    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_X);
    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_Y);
    // From ConfigureAbsSlots(kSlots):
    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_SLOT);
    // From ConfigureRel(REL_WHEEL):
    expect.IoctlSetInt(UI_SET_EVBIT, EV_REL);
    expect.IoctlSetInt(UI_SET_RELBIT, REL_WHEEL);
    // From ConfigureRel(REL_HWHEEL):
    expect.IoctlSetInt(UI_SET_RELBIT, REL_HWHEEL);
    // From ConfigureKey(BTN_TOUCH):
    expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY);
    expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH);
    expect.IoctlSetInt(UI_SET_KEYBIT, BTN_BACK);
    // From ConfigureEnd():
    expect.Write(touchpad->injector[t].GetUiDev(), sizeof(uinput_user_dev));
    expect.IoctlVoid(UI_DEV_CREATE);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0);
  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->Touch(t, 0, 0, 0);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.75f * height);
  expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_PRESS);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->Touch(t, 0.25f, 0.75f, 0.5f);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.99f * width);
  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.99f * height);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->Touch(t, 0.99f, 0.99f, 0.99f);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->Touch(t, 1.0f, 1.0f, 1.0f);
    EXPECT_EQ(EINVAL, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE);
  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->Touch(t, 0.25f, 0.75f, -0.01f);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE);
  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
    touch_status = touchpad->ButtonState(t, 0);
    EXPECT_EQ(0, touch_status);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }

  expect.Reset();
  expect.Close();
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    touchpad->injector[t].record.Reset();
  }
  touch_status = touchpad->Detach();
  EXPECT_EQ(0, touch_status);
  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
    SCOPED_TRACE(t);
    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
  }
}

TEST_F(VirtualTouchpadTest, Badness) {
  std::unique_ptr<VirtualTouchpadForTesting> touchpad(
      VirtualTouchpadForTesting::New());
  UInputRecorder expect;
  UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record;

  status_t touch_status = touchpad->Attach();
  EXPECT_EQ(0, touch_status);

  // Touch off-screen should return an error,
  // and should not result in any system calls.
  expect.Reset();
  record.Reset();
  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f);
  EXPECT_NE(OK, touch_status);
  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f);
  EXPECT_NE(OK, touch_status);
  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f);
  EXPECT_NE(OK, touch_status);
  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f);
  EXPECT_NE(OK, touch_status);
  EXPECT_EQ(expect.GetString(), record.GetString());

  // Unsupported button should return an error,
  // and should not result in any system calls.
  expect.Reset();
  record.Reset();
  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
                                       AMOTION_EVENT_BUTTON_FORWARD);
  EXPECT_NE(OK, touch_status);
  EXPECT_EQ(expect.GetString(), record.GetString());

  // Repeated attach is an error.
  touch_status = touchpad->Attach();
  EXPECT_NE(0, touch_status);
}

}  // namespace dvr
}  // namespace android
