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

#include "arg.h"
#include "common.h"
#include "crd_ut10xx.h"

int
main(int argc, const char **argv)
{
	const char *help = 
		"\n\tfsmng [-help] -devnum=num|-devname=name [-scan] [-clear]\n"
		"\t\t[-list] [-import=file] [-export=file -user|-so -pin=pin]\n\n";
	
	CRD_UT10XX_t *ut;
	CRD_UT10XX_file_t *dfile;
	
	FILE *hfile;
	
	char buf[128 * 1024];
	
	int devnum = -1;
	const char *devname = 0;
	int list = 0;
	int scan = 0;
	int clear = 0;
	const char *import_file = 0;
	const char *export_file = 0;
	int user = 0;
	int so = 0;
	int pinid = -1;
	const char *pin = 0;
	
	int i;
	
	int status = 0;

	if ( prologue(argv, help) )
		return (-1);

	if ( arg_getall(argv, "isbbbssbbs", "-devnum", &devnum, "-devname", &devname, 
		"-list", &list, "-scan", &scan, "-clear", &clear, "-import", &import_file, 
		"-export", &export_file, "-user", &user, "-so", &so, "-pin", &pin) < 0 )
		return (-2);
	
	if ( (devname == 0) && (devnum < 0) )
		devnum = 0;
	
	if (devnum >= 0)
	{
		if ( (ut = CRD_UT10XX_find_by_index(devnum)) == 0 )
		{
			epilogue(stderr, "there is no device of that number, use 'info'"
				" to check\n", 0, 0);
			return (-3);
		}
	}
	else
	{
		if ( (ut = CRD_UT10XX_find_by_name(devname)) == 0 )
		{
			epilogue(stderr, "there is no device of this name, use 'info'"
				" to check\n", 0, 0);
			return (-4);
		}
	}
	
	if (so) pinid = CRD_UT10XX_SO_PIN_ID;
	else pinid = CRD_UT10XX_USER_PIN_ID;
	
	CRD_UT10XX_session_open(ut);

	if ( (status = CRD_UT10XX_fs_get_file_list(ut)) < 0 )
	{
		epilogue(stderr, 0, status, ut);
		return (status);
	}
	
	if (list)
	{
		for (i = 0; i < ut->files_no; i++)
		{
			if (ut->file_names[i] == 0)
				continue;
			
			fprintf(stdout, "[%d][%02X] %s (%d)\n", i, ut->file_types[i], ut->file_names[i], ut->file_sizes[i]);
		}
	}
	
	if (scan)
	{
		if ( (status = CRD_UT10XX_fs_scan(ut, buf)) < 0 )
		{
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
		
		fprintf(stdout, "%s", buf);
	}
	
	if (clear)
	{
		if ( (status = CRD_UT10XX_fs_clear(ut, pin, pinid)) < 0 )
		{
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
	}
	
	if (import_file)
	{
		hfile = fopen(import_file, "w");
		
		if (hfile == 0)
		{
			CRD_UT10XX_session_close(ut);
			fprintf(stderr, "could not open file %s to write\n", import_file);
			epilogue(stderr, 0, status, ut);
			return (-5);
		}
		
		dfile = CRD_UT10XX_file_open(ut, import_file);
		
		if (dfile == 0)
		{
			CRD_UT10XX_session_close(ut);
			fprintf(stderr, "could not read file %s from device\n", import_file);
			epilogue(stderr, 0, 0, ut);
			fclose(hfile);
			return (-6);
		}
		
		status = CRD_UT10XX_file_read(dfile, buf, sizeof(buf));
		
		if (status < 0)
		{
			CRD_UT10XX_file_close(dfile);
			CRD_UT10XX_session_close(ut);
			fclose(hfile);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
		
		fwrite(buf, status, sizeof(*buf), hfile);
		fclose(hfile);
		
		status = CRD_UT10XX_file_close(dfile);
		
		if (status < 0)
		{
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
	}
	
	if (export_file)
	{
		hfile = fopen(export_file, "r");
		
		if (hfile == 0)
		{
			CRD_UT10XX_session_close(ut);
			fprintf(stderr, "could not open file %s to read\n", export_file);
			epilogue(stderr, 0, 0, 0);
			return (-5);
		}
		
		dfile = CRD_UT10XX_file_create(ut, export_file, CRD_UT10XX_FT_UNKN);
		
		if (dfile == 0)
		{
			CRD_UT10XX_session_close(ut);
			fprintf(stderr, "could not create file %s on device\n", export_file);
			epilogue(stderr, 0, 0, ut);
			fclose(hfile);
			return (-6);
		}
		
		status = fread(buf, sizeof(*buf), sizeof(buf), hfile);
		fclose(hfile);
		
		status = CRD_UT10XX_file_write(dfile, buf, status);
		
		if (status < 0)
		{
			CRD_UT10XX_file_close(dfile);
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
		
		status = CRD_UT10XX_file_flush(dfile, pin, pinid);
		
		if (status < 0)
		{
			CRD_UT10XX_file_close(dfile);
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
		
		status = CRD_UT10XX_file_close(dfile);
		
		if (status < 0)
		{
			CRD_UT10XX_session_close(ut);
			epilogue(stderr, 0, status, ut);
			return (status);
		}
	}
	
	CRD_UT10XX_session_close(ut);
	
	return (epilogue(stderr, 0, 0, 0));
}
