/* smdtmain.c
 * Neil Moore <neil@cs.uky.edu>
 *  2 Mar 2000
 *
 * Part of sm2dt.  See COPYRIGHT for copyright information.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <lp.h>
#include <lp_smrd.h>
#include <lp_dtpr.h>
#include <lp_util.h>
#include <lp_graph.h>

#ifndef VERSION
#define VERSION "unknown"
#endif

static void usage(void);
static void version(void);

int main(int argc, char *argv[]) 
{
	const char *infilename = NULL;
	FILE *infile = NULL;
	const char *outbasename = "sm2dt";
	struct lp *prog = NULL;
	clock_t start, end;
	int verbosity = 1;
	int timing = 1;

	while (*++argv != NULL) {
		if(!strcmp(*argv, "-o") || !strcmp(*argv, "--output")) {
			++argv;
			if(*argv == NULL) {
				usage();
				return 1;
			}
			outbasename = *argv;
		} else if(!strncmp(*argv, "-o", 2)) {
			outbasename = *argv + 2;
		} else if(!strncmp(*argv, "--output=", 9)) {
			outbasename = *argv + 9;
		} else if(!strcmp(*argv, "-t") || !strcmp(*argv, "--time")) {
			timing = 1;
		} else if(!strcmp(*argv, "-n") || !strcmp(*argv, "--no-time")) {
			timing = 0;
		} else if(!strcmp(*argv, "-V") || !strcmp(*argv, "--verbose")) {
			verbosity = 2;
		} else if(!strcmp(*argv, "-m") || !strcmp(*argv, "--messages")) {
			verbosity = 1;
		} else if(!strcmp(*argv, "-q") || !strcmp(*argv, "--quiet")) {
			verbosity = 0;
		} else if(!strcmp(*argv, "-v") || !strcmp(*argv, "--version")) {
			version();
			return 0;
		} else if(!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
			usage();
			return 0;
		} else if(!strcmp(*argv, "-")) {
			infilename = NULL;
		} else if((*argv)[0] == '-') {
			usage();
			return 1;
		} else {
			infilename = *argv;
		}		
	}	

	if(verbosity > 1 && infilename)
		fprintf(stderr, "Opening %s for reading...\n", infilename);
	
	if(infilename == NULL)
		infile = stdin;
	else if((infile = fopen(infilename, "r")) == NULL) {
		if(verbosity > 0)
			fprintf(stderr, "cannot open %s: %s\n", infilename, strerror(errno));
		goto failure;
	}

	start=clock();
	prog = lp_malloc(sizeof(struct lp));
	
	if(verbosity > 1)
		fprintf(stderr, "Reading program...\n");
	if(lp_sm_read_file(infile, prog) < 0) {
		if(verbosity > 0) {
			const char *msg = lp_smrd_error();
			if(msg)
				fprintf(stderr, "%s\n", msg);
			fprintf(stderr, "error in input; output not generated\n");
		}
		goto failure;
	}

	if(verbosity > 1)
		fprintf(stderr, "Printing program...\n");
	if(lp_dt_print_program(prog, infilename ? infilename : "(stdin)", outbasename) < 0) {
		if(verbosity > 0) {
			const char *msg = lp_dtpr_error();
			if(msg)
				fprintf(stderr, "%s\n", msg);
			fprintf(stderr, "error generating output\n");
		}
		goto failure;
	}

	end = clock();
	if(timing)
		fprintf(stderr,"conversion: %f seconds\n", ((double)end - start)/ CLOCKS_PER_SEC);

	if(verbosity > 1)
		fprintf(stderr, "Cleaning up...\n");
	if (infile != stdin)
		fclose(infile);
	
	lp_free_lp(prog);
	return 0;
	
 failure:
	if(verbosity > 1)
		fprintf(stderr, "Cleaning up...\n");
	
	if(prog)
		lp_free_lp(prog);
	if(infile && infile != stdin)
		fclose(infile);
	return 1;
}

void usage(void) 
{
	printf("usage: smdtconv [options] [filename]\n");
	printf("Convert a logic program in smodels format into a default theory in DeReS\n");
	printf("format.\n\n");

	printf(" -o, --output=file    output goes to file.{dt,dc,thc} (default \"sm2dt\")\n");
	printf(" -t, --time           print timing information to stderr (default)\n");
	printf(" -n, --no-time        do not print timing information\n");
	printf(" -V, --verbose        print additional information to stderr\n");
	printf(" -m, --messages       print status messages to stderr (default)\n");
	printf(" -q, --quiet          do not print information (other than timing)\n");
	printf(" -v, --version        print version information to stdout\n");
	printf(" -h, --help           display this message\n\n");
	
	printf("Input (in smodels format) is read from filename (defaults to stdin).\n");
}

void version(void) 
{
	printf("smdtconv %s, from lpsms %s, using liblp %s\n", VERSION, lp_sms_version(), lp_version());
}
