#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "ax25.h"
#include "rose.h"

#include "node.h"
#include "mheard.h"
#include "io.h"
#include "axutils.h"
#include "axconfig.h"
#include "procinfo.h"

struct mheard_list {
  struct mheard_struct    data;
  struct mheard_list      *next;
};

int do_mheard(int argc, char **argv)
{
  FILE *fp;
  struct mheard_struct mh;
  struct mheard_list *list, *new, *tmp, *p;
  char *s, *t, *u;
  long ti;

  tputs("\n");

  if (argc > 1) { 
  if (ax25_config_get_dev(argv[1]) == NULL ||
      (check_perms(PERM_HIDDEN, 0) == -1 && is_hidden(argv[1]))) {
    node_msg("Invalid port");
    return 0;
  }
  }
  if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) {
    node_perror(DATA_MHEARD_FILE, errno);
    return 0;
  }
  list = NULL;
  while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) {
    if (argc > 1) { 
    if (strcmp(argv[1], mh.portname)) continue; } 
    if (check_perms(PERM_HIDDEN, 0) == -1 && is_hidden(mh.portname)) continue;
  	
    if ((new = calloc(1, sizeof(struct mheard_list))) == NULL) {
      node_perror("do_mheard: calloc", errno);
      break;
    }
    new->data = mh;
    if (list == NULL || mh.last_heard > list->data.last_heard) {
      tmp = list;
      list = new;
      new->next = tmp;
    } else {
      for (p = list; p->next != NULL; p = p->next)
	if (mh.last_heard > p->next->data.last_heard) break;
      tmp = p->next;
      p->next = new;
      new->next = tmp;
    }
  }
  fclose(fp);
  node_msg("Heard list:");
  tprintf("Callsign  Port    Pkts rcvd Last heard\n");
  tprintf("--------- ------- --------- ------------------------------------------\n");
  while (list != NULL) {
    s = ctime(&list->data.last_heard);
    s[19] = '\0';
    t = ax2asc(&list->data.from_call);
    if ((u = strstr(t, "-0")) != NULL) *u = '\0';
    tprintf("%-9s %-7s %-9ld %s  (", t, list->data.portname, list->data.count, s);
    ti = time(NULL) - list->data.last_heard;
    if (ti < 60L) tprintf("        %3ld sec", ti);
    else if (ti < 3600L) tprintf("%3ld min %3ld sec", ti / 60L, ti % 60L);
    else  tprintf("%3ld  hr %3ld min", ti / 3600L, (ti % 3600L) / 60L);
    tprintf(" ago)\n");
    tmp = list;
    list = list->next;
    free(tmp);
  }
  return 0;
}
