/* acpi.c - show power state
 *
 * Written by Isaac Dunham, 2013
 *
 * No standard.

USE_ACPI(NEWTOY(acpi, "abctV", TOYFLAG_USR|TOYFLAG_BIN))

config ACPI
  bool "acpi"
  default y
  help
    usage: acpi [-abctV]
    
    Show status of power sources and thermal devices.

    -a	Show power adapters
    -b	Show batteries
    -c	Show cooling device state
    -t	Show temperatures
    -V	Show everything
*/

#define FOR_acpi
#include "toys.h"

GLOBALS(
  int ac, bat, therm, cool;
  char *cpath;
)

static int read_int_at(int dirfd, char *name)
{
  int fd, ret=0;
  FILE *fil;

  if ((fd = openat(dirfd, name, O_RDONLY)) < 0) return -1;
  if (!fscanf(fil = xfdopen(fd, "r"), "%d", &ret)) perror_exit_raw(name);
  fclose(fil);

  return ret;
}

static int acpi_callback(struct dirtree *tree)
{
  int dfd, fd, len, on;

  errno = 0;

  if (tree->name[0]=='.') return 0;

  if (!tree->parent)
    return DIRTREE_RECURSE|DIRTREE_SYMFOLLOW;

  if (0 <= (dfd = open((TT.cpath=dirtree_path(tree, NULL)), O_RDONLY))) {
    if ((fd = openat(dfd, "type", O_RDONLY)) < 0) goto done;
    len = readall(fd, toybuf, sizeof(toybuf));
    close(fd);
    if (len < 1) goto done;

    if (!strncmp(toybuf, "Battery", 7)) {
      if ((toys.optflags & FLAG_b) || (!toys.optflags)) {
        int cap = 0, curr = 0, max = 0;

        if ((cap = read_int_at(dfd, "capacity")) < 0) {
          if ((max = read_int_at(dfd, "charge_full")) > 0)
            curr = read_int_at(dfd, "charge_now");
          else if ((max = read_int_at(dfd, "energy_full")) > 0)
            curr = read_int_at(dfd, "energy_now");
          if (max > 0 && curr >= 0) cap = 100 * curr / max;
        }
        if (cap >= 0) printf("Battery %d: %d%%\n", TT.bat++, cap);
      }
    } else if (toys.optflags & FLAG_a) {
      if ((on = read_int_at(dfd, "online")) >= 0)
        printf("Adapter %d: %s-line\n", TT.ac++, (on ? "on" : "off"));
    }
done:
    close(dfd);
  }
  free(TT.cpath);
  return 0;
}

static int temp_callback(struct dirtree *tree)
{
  int dfd, temp;

  if (*tree->name=='.') return 0;
  if (!tree->parent || !tree->parent->parent)
    return DIRTREE_RECURSE|DIRTREE_SYMFOLLOW;
  errno = 0;

  if (0 <= (dfd = open((TT.cpath=dirtree_path(tree, NULL)), O_RDONLY))) {
    if ((0 < (temp = read_int_at(dfd, "temp"))) || !errno) {
      //some tempertures are in milli-C, some in deci-C
      //reputedly some are in deci-K, but I have not seen them
      if (((temp >= 1000) || (temp <= -1000)) && (temp%100 == 0)) temp /= 100;
      printf("Thermal %d: %d.%d degrees C\n", TT.therm++, temp/10, temp%10);
    }
    close(dfd);
  }
  free(TT.cpath);

  return 0;
}

static int cool_callback(struct dirtree *tree)
{
  int dfd=5, cur, max;

  errno = 0;
  memset(toybuf, 0, sizeof(toybuf));

  if (*tree->name == '.') return 0;
  if (!tree->parent) return DIRTREE_RECURSE|DIRTREE_SYMFOLLOW;


  if (0 <= (dfd = open((TT.cpath=dirtree_path(tree, &dfd)), O_RDONLY))) {
    TT.cpath = strcat(TT.cpath, "/type");
    if (readfile(TT.cpath, toybuf, 256) && !errno) {
      toybuf[strlen(toybuf) -1] = 0;
      cur=read_int_at(dfd, "cur_state");
      max=read_int_at(dfd, "max_state");
      if (errno)
        printf("Cooling %d: %s no state information\n", TT.cool++, toybuf);
      else printf("Cooling %d: %s %d of %d\n", TT.cool++, toybuf, cur, max);
    }
    close(dfd);
  }
  free(TT.cpath);
  return 0;
}

void acpi_main(void)
{
  if (toys.optflags & FLAG_V) toys.optflags = FLAG_a|FLAG_b|FLAG_c|FLAG_t;
  if (!toys.optflags) toys.optflags = FLAG_b;
  if (toys.optflags & (FLAG_a|FLAG_b))
    dirtree_read("/sys/class/power_supply", acpi_callback);
  if (toys.optflags & FLAG_t) dirtree_read("/sys/class", temp_callback);
  if (toys.optflags & FLAG_c) dirtree_read("/sys/class/thermal", cool_callback);
}
