/*
 * nasd_edrfs_test.c
 *
 * Test the NASD EDRFS mount operation.
 *
 * Author: Mathew Monroe
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#include <nasd/nasd_options.h>
#include <nasd/nasd_common.h>
#include <nasd/nasd_error.h>
#include <nasd/nasd_mem.h>
#include <nasd/nasd_pdrive_client.h>
#include <nasd/nasd_edrfs_client.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>

#include "nasd_edrfs_test_common.h"
#include "nasd_edrfs_test.h"

static const nasd_edrfs_test_funct_t functions[] = {
  NASD_EDRFS_TEST_FUNCT_MOUNT,
  NASD_EDRFS_TEST_FUNCT_NULL,
  NASD_EDRFS_TEST_FUNCT_FSSTAT,
  NASD_EDRFS_TEST_FUNCT_FSINFO,
  NASD_EDRFS_TEST_FUNCT_LOOKUP,
  NASD_EDRFS_TEST_FUNCT_READDIR,
  NASD_EDRFS_TEST_FUNCT_ACCESS,
  NASD_EDRFS_TEST_FUNCT_CREATE,
  NASD_EDRFS_TEST_FUNCT_SETATTR,
  NASD_EDRFS_TEST_FUNCT_RENAME,
  NASD_EDRFS_TEST_FUNCT_SYMLINK,
  NASD_EDRFS_TEST_FUNCT_REMOVE,
  NASD_EDRFS_TEST_FUNCT_MKDIR,
  NASD_EDRFS_TEST_FUNCT_RMDIR,
  NASD_EDRFS_TEST_FUNCT_NEWCOOKIE,
  NASD_EDRFS_TEST_FUNCT_GETSTATS,
  { NULL, NULL, NULL, NULL, NULL, NULL }
};


static char *program_name;
static int funct = -1;

void usage(void);

void usage(void) {
  int i;
  if((funct != -1) && functions[funct].usage)
    fprintf(stderr, "Usage: %s [options] %s servername result %s\n",
	    program_name, functions[funct].name, functions[funct].usage);
  else{
    fprintf(stderr, "Usage: %s [options] function servername result ...\n",
	    program_name);
    fprintf(stderr, "Available functions include:");
    i = 0;
    while(functions[i].name != NULL){
      fprintf(stderr, " %s", functions[i].name);
      i++;
    }
    fprintf(stderr,"\n");
  }
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "  -v\t[ be more verbose in what we are doing ]\n");
  fflush(stderr);
  exit(1);
}

int verbose;

int main(int argc, char *argv[]) {
  nasd_status_t rc, c_rc;
  nasd_rpc_status_t op_status;
  nasd_edrfs_mount_info_t minfo;
  void *args, *res;
  int i;

  program_name = argv[0];

  if (argc < 2) usage();

  if (strcmp(argv[1], "-v") == 0){
    if (argc < 3) usage();
    verbose = 1;
    for(i=1;i<argc;i++)
      argv[i] = argv[i+1];
    argc--;
  }
  else
    verbose = 0;

  i = 0;
  do {
    if(functions[i].name == NULL){
      fprintf(stderr,"Invalid function %s.", argv[1]);
      usage();
    }
    if(!strcmp(functions[i].name, argv[1]))
      funct = i;
    i++;
  } while (funct == -1);

  if (argc < 4) usage();

  minfo.server_name = argv[2];
  rc = nasd_edrfs_test_rc_convert(argv[3], &c_rc);
  if(rc)
    usage();

  if (verbose) {
    fprintf(stderr, "Deciding what you want done...");
    fflush(stderr);
  }

  if(functions[funct].marshall != NULL){
    rc = functions[funct].marshall(argc - 4, &argv[4], &args);
    if (rc != NASD_SUCCESS)
      usage();
  }
  else if(argc > 4)
    usage();

  minfo.binding_type = NASD_BIND_DEFAULT;

  if (verbose){
    fprintf(stderr, "Done.\nBinding to server...");
    fflush(stderr);
  }

  rc = nasd_edrfs_test_init(&minfo);
  if (rc) {
    fprintf(stderr, "ERROR: initialization failed, aborting. rc=%ld\n",
	    (long)rc);
    exit(rc);
  }
  
  if (verbose){
    fprintf(stderr, "Done.\nMaking edrfs call...");
    fflush(stderr);
  }

  rc = functions[funct].test(minfo.server_handle, args, &res, &op_status);
  
  if (verbose){
    fprintf(stderr, "Done.\n");
    fflush(stderr);
  }

  if ((rc != c_rc) || op_status){
    fprintf(stderr,"FAIL! %d (%s), %d (%s)\n", rc, nasd_error_string(rc),
	    op_status, nasd_error_string(op_status));
    exit(1);
  }
  else
    fprintf(stderr,"PASS\n");

  if(functions[funct].printres != NULL){
    rc = functions[funct].printres(res);
    if(rc){
      fprintf(stderr,"Failed on printing results.\n");
      exit(rc);
    }
  }

  if (verbose){
    fprintf(stderr, "Cleaning up...");
    fflush(stderr);
  }

  if(functions[funct].cleanup != NULL){
    rc = functions[funct].cleanup(args, res);
    if(rc){
      fprintf(stderr,"Failed on cleanup.\n");
      exit(rc);
    }
  }

  if (verbose){
    fprintf(stderr, "Done.\nShutingdown...");
    fflush(stderr);
  }

  rc = nasd_edrfs_test_shutdown(&minfo);
  if (rc) {
    fprintf(stderr, "ERROR: shutdown had errors: rc=%ld\n", (long) rc);
    exit(rc);
  }

  if (verbose){
    fprintf(stderr, "Done.\n");
    fflush(stderr);
  }

  exit(0);
}
