// Copyright 2016 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 <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <fuchsia/hardware/rtc/c/fidl.h>
#include <getopt.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <zircon/syscalls.h>

int usage(const char *cmd) {
  fprintf(stderr,
          "Interact with the real-time or monotonic clocks:\n"
          "   %s                              Print the time\n"
          "   %s --help                       Print this message\n"
          "   %s --set YYYY-mm-ddThh:mm:ss    Set the time\n"
          "   %s --monotonic                  Print nanoseconds since boot\n"
          "   optionally specify an RTC device with --dev PATH_TO_DEVICE_NODE\n",
          cmd, cmd, cmd, cmd);
  return -1;
}

char *guess_dev(void) {
  char path[19];  // strlen("/dev/class/rtc/###") + 1
  DIR *d = opendir("/dev/class/rtc");
  if (!d) {
    return NULL;
  }

  struct dirent *de;
  while ((de = readdir(d)) != NULL) {
    if (strlen(de->d_name) != 3) {
      continue;
    }

    if (isdigit(de->d_name[0]) && isdigit(de->d_name[1]) && isdigit(de->d_name[2])) {
      sprintf(path, "/dev/class/rtc/%.3s", de->d_name);
      closedir(d);
      return strdup(path);
    }
  }

  closedir(d);
  return NULL;
}

zx_status_t open_rtc(const char *path, zx_handle_t *handle) {
  int rtc_fd = open(path, O_RDONLY);
  if (rtc_fd < 0) {
    printf("Can not open RTC device\n");
  }
  return fdio_get_service_handle(rtc_fd, handle);
}

int print_rtc(const char *path) {
  zx_handle_t handle;
  zx_status_t status = open_rtc(path, &handle);
  if (status != ZX_OK) {
    return -1;
  }
  fuchsia_hardware_rtc_Time rtc;

  status = fuchsia_hardware_rtc_DeviceGet(handle, &rtc);
  if (status != ZX_OK) {
    return -1;
  }
  printf("%04d-%02d-%02dT%02d:%02d:%02d\n", rtc.year, rtc.month, rtc.day, rtc.hours, rtc.minutes,
         rtc.seconds);
  return 0;
}

int set_rtc(const char *path, const char *time) {
  fuchsia_hardware_rtc_Time rtc;
  int n = sscanf(time, "%04hd-%02hhd-%02hhdT%02hhd:%02hhd:%02hhd", &rtc.year, &rtc.month, &rtc.day,
                 &rtc.hours, &rtc.minutes, &rtc.seconds);
  if (n != 6) {
    printf("Bad time format.\n");
    return -1;
  }
  zx_handle_t handle;
  zx_status_t status = open_rtc(path, &handle);
  if (status != ZX_OK) {
    printf("Can not open RTC device\n");
    return status;
  }

  zx_status_t set_status;
  status = fuchsia_hardware_rtc_DeviceSet(handle, &rtc, &set_status);
  if (status != ZX_OK) {
    return status;
  }

  return set_status;
}

void print_monotonic(void) { printf("%lu\n", zx_clock_get_monotonic()); }

int main(int argc, char **argv) {
  int err = 0;
  const char *cmd = basename(argv[0]);
  char *path = NULL;
  char *set = NULL;
  static const struct option opts[] = {
      {"set", required_argument, NULL, 's'},
      {"dev", required_argument, NULL, 'd'},
      {"monotonic", no_argument, NULL, 'm'},
      {"help", no_argument, NULL, 'h'},
      {0},
  };
  for (int opt; (opt = getopt_long(argc, argv, "", opts, NULL)) != -1;) {
    switch (opt) {
      case 's':
        set = strdup(optarg);
        break;
      case 'd':
        path = strdup(optarg);
        break;
      case 'm':
        print_monotonic();
        goto done;
      case 'h':
        usage(cmd);
        err = 0;
        goto done;
      default:
        err = usage(cmd);
        goto done;
    }
  }

  argv += optind;
  argc -= optind;

  if (argc != 0) {
    err = usage(cmd);
    goto done;
  }

  if (!path) {
    path = guess_dev();
    if (!path) {
      fprintf(stderr, "No RTC found.\n");
      err = usage(cmd);
      goto done;
    }
  }

  if (set) {
    err = set_rtc(path, set);
    if (err) {
      printf("Set RTC failed.\n");
      usage(cmd);
    }
    goto done;
  }

  err = print_rtc(path);
  if (err) {
    usage(cmd);
  }

done:
  free(path);
  free(set);
  return err;
}
