#include <stdio.h>
#include <stdint.h>
#include <aspoutil.h>

#include "feig.h"
/*
  All section and page referenses are for H20800-18e-ID-B.pdf,
  ask a Feig represenative for the file.
*/

LOG_BUFFER(200)
struct cmdline optv[] = {
  { 's', "serial-spec", "SERIAL_SPEC", "serial_spec", "/dev/ttyS4:38400:8e1", NULL, "what serial port to open and at which speed and settings, e.g. \"/dev/ttyS0:19200:8n1\"" },
};

#define BUFSZ 255
const size_t bufsize = BUFSZ;
uint8_t buf[BUFSZ];

static void Usage(void) {
  printf("Usage:\n"
         "\tTest... [options] [adr] [cmd] [data...]\n"
         );
  printf("Description:\n");
  LOG_IF(cmdline_usage(CMDLINE_SZ(optv), optv, "\t"), LOG_ERR) { }

  exit(1);
}

int main(int argc, char *argv[]) {
  int ix;
  uint8_t com_adr;
  uint8_t cmd;
  uint8_t *data;
  uint16_t data_len;
  int fd;
  struct termios save;
  int len;
  int ret;
  struct openraw_t sp;
  char optbuf[40];

  (void) cmdline_extrpgm(argv);
  log_open(NULL, 0, 0);
  if ( cmdline_getopt(argc, argv, CMDLINE_SZ(optv), optv) < 0 ) {
    Usage();
  }
  if (argc - optind < 2) Usage();

  LOG_IF (strlen(optv[0].arg_value) >= 40, LOG_CRIT) exit(1);
  strcpy(optbuf, optv[0].arg_value);
  LOG_IF( tty_parse_argv(optbuf, &sp) < 0, LOG_ERR) Usage();
  LOG_IF( (fd = tty_openraw(NULL, NULL, 0, &sp)) < 0, LOG_ERR) return -1;
  /*printf("opened %s\n", sp.dev); */

  argc -= optind;
  argv += optind;

  len = feig_strcmd(buf, bufsize, argc, argv);
  if (len < 0) return 1;

  feig_prtpkg(NULL, buf, len);
  feig_verify_pkg(buf, BUFSZ, &com_adr, &cmd, &data, &data_len);
  /*printf("adr cmd data_len, data: %02x %02x %d:", com_adr, cmd, data_len); */
  /*for (ix = 0; ix < data_len; ++ix) printf(" %02x", data[ix]); */
  /*printf("\n"); */

  LOG_IFERRNO( (ret = write(fd, buf, len)) == -1 || ret != len, LOG_ERR ) goto End;
  /*printf("write len = %d\n", ret); */
  memset( buf, 0, BUFSZ);
  ret = 0;
  sleep(1);
  while (1) {
    LOG_IFERRNO( (ret = read(fd, buf, BUFSZ)) == -1, LOG_ERR ) goto End;
    /*printf("read len = %d\n", ret); */
    if (ret > 0) break;
    sleep(1);
  }

  if (feig_verify_pkg(buf, ret, &com_adr, &cmd, &data, &data_len) > 0) {
    feig_prtpkg(NULL, buf, ret);
    /*printf("adr cmd data_len, data: %02x %02x %d:", com_adr, cmd, data_len); */
    feig_check_status(data[0], 0);
    data++;
    data_len--;
    /*for (ix = 0; ix < data_len; ++ix) printf(" %02x", data[ix]); */
    /*printf("\n"); */
  } else {
    printf("Strange input:");
    for (ix = 0; ix < ret; ++ix) printf(" %02x", buf[ix]);
    printf("\n");
  }

 End:
  LOG_VIF( tty_close(fd, &save, sp.dev, getpid()), LOG_ERR, " dev = %s", sp.dev) {}
  return 0;
}
