// Copyright (c) 2003 MBARI
// Monterey Bay Aquarium Research Institute Proprietary Information.
// All Rights Reserved.
//
#include <string.h>
#include <unistd.h>
#include <unix.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

#define NARGS 8

/** This program opens a socket with to an AUV portal. The program
sends its address and a list of mission log directories to the portal.
*/

// Function explaining usage of the program
//
void usage(void)
{
  fprintf(stdout, "%s%s%s%s%s%s%s%s%s",
	"usage: adx  PortalName  DataName  login  pass  port  survey  dir  [dir2 ...]\n",
        "  PortalName is the hostname of the portal\n",
        "  DataName is the hostname where the auv data resides\n",
        "  login is the login account on DataName that the portal will use\n",
        "  pass is the password to the login on DataName\n",
        "  port is the port number used for the service\n",
        "  SSDS survey name (e.g., AUVCTD_2003_191)\n",
        "  dir is the FULL path name of the data directory to copy\n",
        "  dir2 etc. are (optionally) more data directories to copy\n"
	  );
}

// Main auvDataXfer program
//
main(int argc, char **argv) {

  //****************************
  // Ensure correct usage

  // minimum args -> serverhostname clienthostname login passwd directory
  // Order of args is significant as well
  //
  if (argc < NARGS)
  {
    usage();
    return 1;
  }

  //
  //============================

  //****************************
  // Establish a socket connection to the portal
  //
  char *portalHost = argv[1];

  int sock;
  struct sockaddr_in server;
  char buf[2048], portalbuf[4096];

  // Create socket
  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("opening socket stream");
    return 1;
  }

  // Connect socket to portal host
  server.sin_family = AF_INET;
  struct hostent *hp = gethostbyname(portalHost);
  if (hp == 0) {
    fprintf(stderr, "Couldn't connect to portal host \"%s\"\n", portalHost);
    return 1;
  }

  // Get the port we're connecting to
  long serverPort = atol(argv[5]);

  bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
  server.sin_port = htons(serverPort);

  // Connect to portal server
  if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
    perror("connecting stream socket");
    return 1;
  }

  //
  //============================

  //****************************
  // Assemble the data to send to the portal

  // Get localhost info
  //
  struct hostent *client = gethostbyname(argv[2]);
  if (client == 0)
  {
    fprintf(stderr, "\t; Couldn't get client host info for \n");
    return 1;
  }

  // Convert the host address from network to ascii string
  //
  char *in_addr_string = inet_ntoa(*((struct in_addr*)client->h_addr));

  // Place non-recurring info in the portal command buffer
  //
  sprintf(portalbuf,"%s;%s;%s;%s", in_addr_string, argv[3], argv[4], argv[6]);

  // Now, concat the gzipped-datafiles filenames
  //
  for (int dir = 6; dir < argc; dir++)
  {
    // Peel off trailing slash if necessary
    //
    char *thisDir = argv[dir];
    while ('/' == thisDir[strlen(thisDir)-1])
    {
      thisDir[strlen(thisDir)-1] = '\0';
    }

    // Change dir to the parent of the given directory, 
    // or skip to next if unsuccessful
    //
    char *datadir = 0, *cursor = 0;
    cursor = strrchr(thisDir, '/');
    if (cursor == NULL)
    {
      fprintf(stderr, "\t; Bad directory specification (%s), skipping...\n",
	      thisDir);
      continue;
    }

    datadir = strdup(cursor+1);
    *cursor = '\0';
    
    fprintf(stdout, "\t; cd %s ...\n", thisDir);
    if (-1 == chdir(thisDir))
    {
      fprintf(stderr, "\t; Can't find directory %s, skipping...\n", thisDir);
      continue;
    }

    // Tar all the log files, skip to next if unsuccessful
    sprintf(buf, "tar cvf %s_data.tar %s", datadir, datadir);
    fprintf(stdout, "\t; %s ...\n", buf);
    if (-1 == system(buf))
    {
      fprintf(stderr, "\t; tar command failed, skipping...\n");
      continue;
    }

    // gzip the tar file, skip to next if unsuccessful
    sprintf(buf, "gzip -f %s_data.tar", datadir);
    fprintf(stdout, "\t; %s ...\n", buf);
    if (-1 == system(buf))
    {
      fprintf(stderr, "\t; gzip command failed on, skipping...\n");
      continue;
    }

    // move the .tar.gz file to the data directory,
    // or skip to next if unsuccessful
    //
    sprintf(buf, "mv %s_data.tar.gz %s/.", datadir, datadir);
    fprintf(stdout, "\t; %s ...\n", buf);
    if (-1 == system(buf))
    {
      fprintf(stderr, "\t; mv command failed, skipping...\n");
      continue;
    }

    sprintf(buf, ";%s/%s/%s_data.tar.gz", thisDir, datadir, datadir);
    strcat(portalbuf, buf);

    //
    //============================

  }

  //****************************
  // Send the command to the portal
  fprintf(stdout, "\t; Portal message: %s\n", portalbuf);

  if (write(sock, portalbuf, strlen(portalbuf)) < 0) {
    perror("writing message to stream socket");
    fprintf(stderr, "\t; Socket comms error, skipping...\n");
  }

  //
  //============================

  return 0;
}

