/* hwclock.c - get and set the hwclock
 *
 * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com>
 *
 * No standard, but see Documentation/rtc.txt in the linux kernel source..
 *
USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_USR|TOYFLAG_BIN))

config HWCLOCK
  bool "hwclock"
  default y
  help
    usage: hwclock [-rswtluf]

    -f FILE Use specified device file instead of /dev/rtc (--rtc)
    -l      Hardware clock uses localtime (--localtime)
    -r      Show hardware clock time (--show)
    -s      Set system time from hardware clock (--hctosys)
    -t      Set the system time based on the current timezone (--systz)
    -u      Hardware clock uses UTC (--utc)
    -w      Set hardware clock from system time (--systohc)
*/

#define FOR_hwclock
#include "toys.h"
#include <linux/rtc.h>

GLOBALS(
  char *fname;

  int utc;
)

static int rtc_find(struct dirtree* node)
{
  FILE *fp;

  if (!node->parent) return DIRTREE_RECURSE;

  sprintf(toybuf, "/sys/class/rtc/%s/hctosys", node->name);
  fp = fopen(toybuf, "r");
  if (fp) {
    int hctosys = 0, items = fscanf(fp, "%d", &hctosys);

    fclose(fp);
    if (items == 1 && hctosys == 1) {
      sprintf(toybuf, "/dev/%s", node->name);
      TT.fname = toybuf;

      return DIRTREE_ABORT;
    }
  }

  return 0;
}

void hwclock_main()
{
  struct timezone tzone;
  struct timeval timeval;
  struct tm tm;
  time_t time;
  int fd = -1;

  // check for Grenich Mean Time
  if (toys.optflags & FLAG_u) TT.utc = 1;
  else {
    FILE *fp;
    char *s = 0;

    for (fp = fopen("/etc/adjtime", "r");
         fp && getline(&s, (void *)toybuf, fp)>0;
         free(s), s = 0) TT.utc += !strncmp(s, "UTC", 3);
    if (fp) fclose(fp);
  }

  if (!(toys.optflags&FLAG_t)) {
    int w = toys.optflags & FLAG_w, flag = O_WRONLY*w;

    // Open /dev/rtc (if your system has no /dev/rtc symlink, search for it).
    if (!TT.fname && (fd = open("/dev/rtc", flag)) == -1) {
      dirtree_read("/sys/class/rtc", rtc_find);
      if (!TT.fname) TT.fname = "/dev/misc/rtc";
    }
    if (fd == -1) fd = xopen(TT.fname, flag);

    // Get current time in seconds from rtc device. todo: get subsecond time
    if (!w) {
      char *s = s;

      xioctl(fd, RTC_RD_TIME, &tm);
      if (TT.utc) s = xtzset("UTC0");
      if ((time = mktime(&tm)) < 0) error_exit("mktime failed");
      if (TT.utc) {
        free(xtzset(s));
        free(s);
      }
    }
  }

  if (toys.optflags & (FLAG_w|FLAG_t)) {
    if (gettimeofday(&timeval, 0)) perror_exit("gettimeofday failed");
    if (!(TT.utc ? gmtime_r : localtime_r)(&timeval.tv_sec, &tm))
      error_exit(TT.utc ? "gmtime_r failed" : "localtime_r failed");
  }

  if (toys.optflags & FLAG_w) {
    /* The value of tm_isdst is positive if daylight saving time is in effect,
     * zero if it is not and negative if the information is not available. 
     * todo: so why isn't this negative...? */
    tm.tm_isdst = 0;
    xioctl(fd, RTC_SET_TIME, &tm);
  } else if (toys.optflags & FLAG_s) {
    tzone.tz_minuteswest = timezone / 60 - 60 * daylight;
    timeval.tv_sec = time;
    timeval.tv_usec = 0; // todo: fixit
  } else if (toys.optflags & FLAG_t) {
    // Adjust seconds for timezone and daylight saving time
    // extern long timezone is defined in header sys/time.h
    tzone.tz_minuteswest = timezone / 60;
    if (tm.tm_isdst) tzone.tz_minuteswest -= 60;
    if (!TT.utc) timeval.tv_sec += tzone.tz_minuteswest * 60;
  } else {
    char *c = ctime(&time), *s = strrchr(c, '\n');

    if (s) *s = '\0';
    // TODO: implement this.
    xprintf("%s  0.000000 seconds\n", c);
  }
  if (toys.optflags & (FLAG_t|FLAG_s)) {
    tzone.tz_dsttime = 0;
    if (settimeofday(&timeval, &tzone)) perror_exit("settimeofday failed");
  }

  if (fd != -1) close(fd);
}
