#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "ax25.h"

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

int do_links(int argc, char **argv)
{
  struct ax_routes *axrt, *p;
  char digipath[AX25_MAX_DIGIS*10];
  char tipoconn[9];  
  int i=0;

  tputs("\n");
  if ((axrt=read_ax_routes()) == NULL) {
    if (errno) node_perror("do_links: read_ax_routes", errno);
    else node_msg("No known routes");
    return 0;
  }

  /* "links" */
  if (argc == 1) {
    node_msg("AX25 Links:");
    tprintf("Call      Alias     Description\n");
    tprintf("--------- --------- ------------------------------------------------------------\n");                        
    for(p=axrt;p!=NULL;p=p->next) 
      tprintf("%-9s %-9s %s\n", p->dest_call, p->alias, p->description);
    free_ax_routes(axrt);
    return 0;
  }

  
/* "links d" */
  if ((*argv[1]=='d') && (strlen(argv[1])==1)) {
    node_msg("AX25 Direct Links:");
    tprintf("Call      Alias     Port    Description\n");
    tprintf("--------- --------- ------- ----------------------------------------------------\n");
    for(p=axrt;p!=NULL;p=p->next) 
    {  if (*p->conn_type==CONN_TYPE_DIRECT)  tprintf("%-9s %-9s %-7s %s\n", p->dest_call, p->alias, p->dev, p->description); }
    free_ax_routes(axrt);
    return 0;
  }
  
  
/* "links n" */
  if ((*argv[1]=='n') && (strlen(argv[1])==1)) {
    node_msg("AX25 Links via other nodes:");
    tprintf("Call      Alias     Port    Routing   Description\n");
    tprintf("--------- --------- ------- --------- ------------------------------------------\n");
    for(p=axrt;p!=NULL;p=p->next) 
    { if (*p->conn_type==CONN_TYPE_NODE) tprintf("%-9s %-9s %-7s %-9s %s\n", p->dest_call, p->alias, p->dev, p->digis[0], p->description); }
    free_ax_routes(axrt);
    return 0;
  }
  
  
  
/* "links v" */
  if ((*argv[1]=='v') && (strlen(argv[1])==1)) {
    node_msg("AX25 Links via digipeaters:");
    tprintf("Call      Alias     Port    Digipeaters\n");
    tprintf("--------- --------- ------- ----------------------------------------------------\n");
    for(p=axrt;p!=NULL;p=p->next) {
      *digipath='\0';
      for(i=0;i<AX25_MAX_DIGIS;i++) {
	if (p->digis[i]==NULL) break;
	if (i!=0) strcat(digipath," ");
	strcat(digipath, p->digis[i]);
      }
      if (*p->conn_type==CONN_TYPE_DIGI) tprintf("%-9s %-9s %-7s %s\n", p->dest_call, p->alias,  p->dev, digipath);
    }
    free_ax_routes(axrt);
    return 0;
  }

      /* "links <call>" */
  p=find_route(argv[1], axrt);
  if(p!=NULL) {
    node_msg("AX25 Link to %s:", p->dest_call);
    tprintf("Call      Alias     Port    Type     Description\n");
    tprintf("--------- --------- ------- -------- -------------------------------------------\n");
    switch(*p->conn_type) {
    case CONN_TYPE_DIRECT:
    { strcpy(tipoconn,"Direct"); break; }
    case CONN_TYPE_NODE:
    { strcpy(tipoconn,"Via Node"); break; }
    case CONN_TYPE_DIGI:
    { strcpy(tipoconn,"Via Digi"); break; }
    }
    tprintf("%-9s %-9s %-7s %-8s %s\n", p->dest_call, p->alias, p->dev, tipoconn, p->description);
  } else {
    node_msg("No such link");
  }

  free_ax_routes(axrt);
  return 0;
}

int do_dest(int argc, char **argv)
{
  struct flex_dst *fdst, *p;
  struct flex_gt *flgt, *q;
  char ssid[5];
  int i=0;

  tputs("\n");
  if ((fdst=read_flex_dst()) == NULL) {
    if (errno) node_perror("do_dest: read_flex_dst", errno);
    else node_msg("No known destinations");
    return 0;
  }

  /* "dest" */
  if (argc == 1) {
    node_msg("FlexNet Destinations:");
    for (p=fdst;p!=NULL;p=p->next) {
      sprintf(ssid, "%d-%d", p->ssida, p->sside);
      tprintf("%-7s %-5s %4ld%s",p->dest_call,ssid,p->rtt,(++i % 4) ? "  " : "\n");
    }
    if ((i % 4) != 0) tprintf("\n");
    free_flex_dst(fdst);
    return 0;
  }
  if ((flgt=read_flex_gt()) == NULL) {
    node_perror("do_dest: read_flex_gt", errno);
    return 0;
  }
  /* "dest *" */
  if (*argv[1]=='*') {
    node_msg("FlexNet Destinations:");
    tprintf("Dest     SSID    RTT Gateway\n");
    tprintf("-------- ----- ----- --------\n");
    for(p=fdst;p!=NULL;p=p->next) {
      sprintf(ssid, "%d-%d", p->ssida, p->sside);
      q=find_gateway(p->addr,flgt);
      tprintf("%-8s %-5s %5ld %-8s\n", p->dest_call, ssid, p->rtt, q!=NULL?q->call:"?");
    }
    free_flex_dst(fdst);
    free_flex_gt(flgt);
    return 0;
  }
  /* "dest <call>" */
  p=find_dest(argv[1], fdst);
  if(p!=NULL) {
    node_msg("FlexNet Destination %s:", p->dest_call);
    tprintf("Dest     SSID    RTT Gateway\n");
    tprintf("-------- ----- ----- --------\n");
    sprintf(ssid, "%d-%d", p->ssida, p->sside);
    q=find_gateway(p->addr,flgt);
    tprintf("%-8s %-5s %5ld %-8s\n", p->dest_call, ssid, p->rtt, q!=NULL?q->call:"?");
  } else {
    node_msg("No such destination");
  }

  free_flex_dst(fdst);
  free_flex_gt(flgt);

  return 0;
}


