/*
 * Copyright (C) 2016 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 <poll.h>
#include <sys/select.h>
#include <unistd.h>

#include <memory>

#include <base/logging.h>
#include <brillo/flag_helper.h>

#include <peripheralmanager/peripheral_manager_client.h>

int main(int argc, char* argv[]) {
  DEFINE_string(pin, "", "Pin to watch");
  DEFINE_bool(select, false, "Use select instead of poll");
  brillo::FlagHelper::Init(argc, argv, "Watches a GPIO.");
  logging::InitLogging(logging::LoggingSettings());

  std::string pin_name = "IO1";
  if (!FLAGS_pin.empty())
    pin_name = FLAGS_pin;

  // Get a client to the PeripheralManager.
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  if (!client) {
    LOG(ERROR) << "Failed to connect to client";
    return 1;
  }

  // Open GPIO pin.
  BGpio* my_gpio;
  if (BPeripheralManagerClient_openGpio(client, pin_name.c_str(), &my_gpio)) {
    LOG(ERROR) << "Failed to open Gpio";
    return 1;
  }

  // Set the direction to in.
  if (BGpio_setDirection(my_gpio, DIRECTION_IN)) {
    LOG(ERROR) << "Failed to set gpio pin direction";
    return 1;
  }

  // Set the edge trigger type for interrupts.
  if (BGpio_setEdgeTriggerType(my_gpio, BOTH_EDGE)) {
    LOG(ERROR) << "failed to set the edge type";
    return 1;
  }

  // Get the file descriptor used to poll for data.
  int fd = -1;
  if (BGpio_getPollingFd(my_gpio, &fd)) {
    LOG(ERROR) << "failed to get the fd";
    return 1;
  }

  if (FLAGS_select) {
    fd_set ifds;
    FD_ZERO(&ifds);
    FD_SET(fd, &ifds);

    for (int i = 0; i < 30; i++) {
      select(fd + 1, NULL, NULL, &ifds, NULL);
      LOG(INFO) << "received event";
      BGpio_ackInterruptEvent(fd);
    }
  } else {
    struct pollfd poller = {
      .fd = fd,
      .events = POLLPRI | POLLERR,
      .revents = 0,
    };

    for (int i = 0; i < 30; i++) {
      // Poll with no timeout.
      poll(&poller, 1, -1);
      LOG(INFO) << "received an event ";
      BGpio_ackInterruptEvent(fd);
      poller.revents = 0;
    }
  }

  close(fd);

  // Release the gpio pin
  BGpio_delete(my_gpio);

  // Close the connection to PeripheralManager.
  BPeripheralManagerClient_delete(client);

  LOG(INFO) << "Exiting";
  return 0;
}
