/* Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>
#include <sys/poll.h>
#include <sys/signalfd.h>
#include <sys/timerfd.h>

#include <base/files/file_path.h>
#include <base/format_macros.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>

#include <brillo/flag_helper.h>
#include <brillo/streams/file_stream.h>
#include <brillo/streams/stream_utils.h>

// Define defaults that work on the Dragonboard 410c.
const int kDefaultGpioPortOffset = 902;
const int kDefaultGpioOut = 24;
const int kDefaultGpioIn = 28;

// GPIO sysfs path
const char* const kGPIOSysfsPath = "/sys/class/gpio";
// GPIO polling timeout in milliseconds
const int kPollTimeoutMsecs = 3000; /* 3 seconds */
const int kBufSize = 10;

namespace {

/*
 * Get a file stream for GPIO export
 * bool write: access mode with true for write
 * return: file stream pointer
 */
brillo::StreamPtr GetGPIOExportStream(bool write) {
  std::string gpio_path;
  gpio_path = base::StringPrintf("%s/export", kGPIOSysfsPath);
  base::FilePath dev_path{gpio_path};
  auto access_mode = brillo::stream_utils::MakeAccessMode(!write, write);
  return brillo::FileStream::Open(
      dev_path, access_mode, brillo::FileStream::Disposition::OPEN_EXISTING,
      nullptr);
}

/*
 * Get a file stream for GPIO data
 * int gpio: GPIO pin number
 * std::string type: GPIO type e.g. direction, edge, value
 * bool write: access mode with true for write
 * return: file stream pointer
 */
brillo::StreamPtr GetGPIODataStream(int gpio, const std::string type, bool write) {
  std::string gpio_path;
  gpio_path = base::StringPrintf("%s/gpio%d/%s", kGPIOSysfsPath, gpio, type.c_str());
  base::FilePath dev_path{gpio_path};
  auto access_mode = brillo::stream_utils::MakeAccessMode(!write, write);
  return brillo::FileStream::Open(
      dev_path, access_mode, brillo::FileStream::Disposition::OPEN_EXISTING,
      nullptr);
}

}  // anonymous namespace

/*
 * Export GPIO to user space
 * int gpio: GPIO pin number
 */
void export_gpio(int gpio) {

  brillo::StreamPtr stream = GetGPIOExportStream(true);
  if (!stream)
    return;

  std::string value = base::StringPrintf("%d", gpio);
  stream->WriteAllBlocking(value.data(), value.size(), nullptr);
}

/*
 * Write to GPIO
 * std::string type: what GPIO type i.e. direction, value, edge
 * std::string v: value to be written
 * return: true
 */
bool write_gpio(int gpio, const std::string type, std::string v) {

  brillo::StreamPtr stream = GetGPIODataStream(gpio, type, true);
  if (!stream)
    return false;

  stream->WriteAllBlocking(v.data(), v.size(), nullptr);
  return true;
}

/*
 * This method polls GPIO pin for 0 -> 1 transition.
 * int gpio: GPIO pin to be polled.
 * return:
 *   true if polling reads back successfully
 *   false if GPIO open error or polling error
 */
bool poll_gpio(int gpio) {
  char buf[kBufSize];
  struct pollfd fdset[1];
  int nfds = 1;
  int fd = -1;
  int rc = -1;
  int len = -1;

  std::string gpio_path;
  gpio_path = base::StringPrintf("%s/gpio%d/value", kGPIOSysfsPath, gpio);
  fd = open(gpio_path.c_str(), O_RDONLY | O_NONBLOCK );
  if (fd < 0) {
     PLOG(ERROR) << "GPIO open error";
     return false;
  }

  // Use this sawZeroValue to ignore the first spurious interrupt.
  bool sawZeroValue = false;

  while(1) {
    memset((void*)fdset, 0, sizeof(fdset));
    fdset[0].fd = fd;
    fdset[0].events = POLLPRI;

    rc = poll(fdset, nfds, kPollTimeoutMsecs);
    if (rc < 0) {
      PLOG(ERROR) << "poll() failed!";
      close(fd);
      return false;
    } else if (rc == 0) {
      LOG(INFO) << "polling...";
    } else if (fdset[0].revents & POLLPRI) {
      len = read(fdset[0].fd, buf, kBufSize - 1);
      lseek(fdset[0].fd, 0, SEEK_SET);
      if (len >= 0) {
        buf[len] = '\0';
      }
      // TODO: http://b/25317933 Handle the case where read()
      // might result in multiple events being read.
      if (buf[0] == '0') {
        LOG(INFO) << "First interrupt with value 0 ignored.";
        sawZeroValue = true;
        continue;
      }
      if (sawZeroValue && buf[0] == '1') {
        LOG(INFO) << "GPIO pin reset and interrupt with value 1 caught.";
        close(fd);
        return true;
      }
    }
  }
  close(fd);
  return true;
}

int main(int argc, char **argv) {
  int gpio_out = -1;
  int gpio_in = -1;
  int goffset = kDefaultGpioPortOffset;

  DEFINE_int32(gin, 28, "GPIO input");
  DEFINE_int32(gout, 24, "GPIO output");
  DEFINE_int32(goffset, 902, "GPIO port offset for Dragonboard");
  brillo::FlagHelper::Init(argc, argv, "GPIO Playground.");

  if (argc == 1 || argc == 3 || argc == 4) {
    if (FLAGS_goffset) {
      goffset = FLAGS_goffset;
    }
    gpio_out = FLAGS_gout + goffset;
    gpio_in = FLAGS_gin + goffset;
  } else {
    printf("Pass input & output GPIO pin as follows\n");
    printf("adb shell '/system/bin/gpio_playground --gin=28 --gout=24 --goffset=902 &'\n");
    return -1;
  }

  LOG(INFO) << "Export pin " << kDefaultGpioOut << " to userspace";
  export_gpio(gpio_out);
  LOG(INFO) << "Set pin " << kDefaultGpioOut << " direction to out";
  write_gpio(gpio_out, "direction", "out");
  LOG(INFO) << "Set pin " << kDefaultGpioOut << " value to 1";
  write_gpio(gpio_out, "value", "1");

  LOG(INFO) << "Export pin " << kDefaultGpioIn << " to userspace";
  export_gpio(gpio_in);
  LOG(INFO) << "Set pin " << kDefaultGpioIn << " direction to in";
  write_gpio(gpio_in, "direction", "in");
  LOG(INFO) << "Set pin " << kDefaultGpioIn << " edge to both";
  write_gpio(gpio_in, "edge", "both");

  if (poll_gpio(gpio_in)) {
    LOG(INFO) << "Pin " << kDefaultGpioIn << " pushed. Now turn off LED";
    write_gpio(gpio_out, "value", "0");
  }
  return 0;
}
