// Copyright 2017 The Chromium OS 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 <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <stdio.h>

#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/flag_helper.h>

namespace {

constexpr struct input_event kSync = {
    .type = EV_SYN, .code = SYN_REPORT, .value = 0};

constexpr int kBitsPerInt = sizeof(uint32_t) * 8;
constexpr int kMaxInputDev = 256;
// When creating an input device, time delay before send out events to it.
constexpr base::TimeDelta kUinputDevInjectDelay =
    base::TimeDelta::FromSeconds(1);
constexpr char kUinputDev[] = "/dev/uinput";
const int kMaxBit = std::max(std::max(EV_MAX, KEY_MAX), SW_MAX);
const int kMaxInt = (kMaxBit - 1) / kBitsPerInt + 1;

bool TestBit(const uint32_t bitmask[], int bit) {
  return ((bitmask[bit / kBitsPerInt] >> (bit % kBitsPerInt)) & 1);
}

bool HasEventBit(int fd, int event_type, int bit) {
  uint32_t bitmask[kMaxInt];
  memset(bitmask, 0, sizeof(bitmask));
  if (ioctl(fd, EVIOCGBIT(event_type, sizeof(bitmask)), bitmask) < 0)
    return false;
  return TestBit(bitmask, bit);
}

void LogErrorExit(const std::string& message) {
  LOG(ERROR) << message;
  exit(1);
}

// CreateEvent return a correctly filled input_event. It aborts on
// invalid |code| or |value|.
// |code|: "tablet", "lid"
// |value|: 0, 1
struct input_event CreateEvent(const std::string& code, int32_t value) {
  struct input_event event;
  event.type = EV_SW;
  if (code == "tablet")
    event.code = SW_TABLET_MODE;
  else if (code == "lid")
    event.code = SW_LID;
  else
    LogErrorExit("--code=<tablet|lid>");
  if (value != 0 && value != 1)
    LogErrorExit("--value=<0|1>");
  event.value = value;
  return event;
}

// Create an input device which supports given event |type|
// and |code| with uinput interface. It will be alive for
// |lifetime|.
base::ScopedFD CreateDevice(int type, int code, base::TimeDelta lifetime) {
  base::ScopedFD fd(open(kUinputDev, O_RDWR | O_CLOEXEC));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "Failed to open " << kUinputDev;
    return base::ScopedFD();
  }
  int ui_set_type_bit;
  switch (type) {
    case EV_SW:
      ui_set_type_bit = UI_SET_SWBIT;
      break;
    case EV_KEY:
      ui_set_type_bit = UI_SET_KEYBIT;
      break;
    default:
      LOG(FATAL) << "not handled type: " << type;
  }

  if (TEMP_FAILURE_RETRY(ioctl(fd.get(), UI_SET_EVBIT, type))) {
    PLOG(ERROR) << "ioctl ui_set_evbit";
    return base::ScopedFD();
  }
  if (TEMP_FAILURE_RETRY(ioctl(fd.get(), ui_set_type_bit, code))) {
    PLOG(ERROR) << "ioctl ui_set_type_bit";
    return base::ScopedFD();
  }
  struct uinput_user_dev dev;
  memset(&dev, 0, sizeof(dev));
  snprintf(dev.name, sizeof(dev.name), "inject powerd");
  TEMP_FAILURE_RETRY(write(fd.get(), &dev, sizeof(dev)));
  if (TEMP_FAILURE_RETRY(ioctl(fd.get(), UI_DEV_CREATE))) {
    PLOG(ERROR) << "ioctl ui_dev_create";
    return base::ScopedFD();
  }
  // Create a child process to hold this fd to keep created
  // device alive.
  if (fork() == 0) {
    setsid();
    sleep(lifetime.InSeconds());
    exit(0);
  }
  // Give powerd time to open new created device.
  sleep(kUinputDevInjectDelay.InSeconds());
  return fd;
}

// Find the event device which supports said |type| and |code| and
// return opened file descriptor to it.
base::ScopedFD OpenDevice(int type, int code) {
  base::ScopedFD fd;
  for (int i = 0; i < kMaxInputDev; ++i) {
    fd.reset(open(base::StringPrintf("/dev/input/event%d", i).c_str(),
                  O_RDWR | O_CLOEXEC));
    if (!fd.is_valid())
      break;
    if (HasEventBit(fd.get(), 0, type) && HasEventBit(fd.get(), type, code))
      break;
  }
  return fd;
}

void InjectEvent(const struct input_event& event,
                 bool create_dev,
                 base::TimeDelta lifetime) {
  base::ScopedFD fd = OpenDevice(event.type, event.code);
  if (!fd.is_valid()) {
    if (!create_dev) {
      LogErrorExit("No supported input device, try --create_dev");
    }
    fd = CreateDevice(event.type, event.code, lifetime);
    if (!fd.is_valid()) {
      LogErrorExit("Failed to create device");
    }
  }

  TEMP_FAILURE_RETRY(write(fd.get(), &event, sizeof(event)));
  TEMP_FAILURE_RETRY(write(fd.get(), &kSync, sizeof(kSync)));
}

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_string(code, "", "Input event type to inject (one of tablet, lid)");
  DEFINE_int32(value, -1, "Input event value to inject (0 is off, 1 is on)");
  DEFINE_bool(create_dev, false,
              "Create device if no device supports wanted input event");
  DEFINE_int32(dev_lifetime, 300, "Lifetime (in seconds) of created device");

  brillo::FlagHelper::Init(argc, argv, "Inject input events to powerd.\n");

  struct input_event event = CreateEvent(FLAGS_code, FLAGS_value);

  InjectEvent(event, FLAGS_create_dev,
              base::TimeDelta::FromSeconds(FLAGS_dev_lifetime));
  return 0;
}
