/* CREATES - handle CREATE functionality */
#include <ctype.h>
#include "tdhkit.h"
#include "shsql.h"

extern int unlink();

#define CREATE 0
#define DROP 1

#define DATABASE 0
#define TABLE 1
#define INDEX 2


int
main( argc, argv )
int argc;
char **argv;
{
int i, stat, objtype;
char buf[1024], tablename[MAXPATH], filename[MAXPATH], fakename[MAXPATH];
FILE *fp;
int argi;
char ixtypestr[255];
int numflag;
int error;
int laterflag;
int ntablefields;
char *TDH_fieldn();

TDH_errprog( "shsql_create" );

if( argc < 3 ) {
	fprintf( stderr, "usage:  shsql_create  table|index ...\n" );
	exit( 1 );
	} 

argi = 1;
if( stricmp( argv[ argi ], "table" )==0 ) objtype = TABLE;
else if( stricmp( argv[ argi ], "index" )==0 ) objtype = INDEX;

argi++;



stat = SHSQL_allconfig();
if( stat != 0 ) exit( 1 );

if( objtype == TABLE ) {
	/* create table tablename fieldname1 .. fieldnameN  */

	strcpy( tablename, argv[ argi++ ] );

	/* create data file.. */
	sprintf( filename, "%s/data/%s", SHSQL_projdir, tablename );

	fp = fopen( filename, "r" );
	if( fp != NULL ) { fprintf( stderr, "create table error: data table file %s already exists\n", tablename ); exit( 1 ); }

	fp = fopen( filename, "w" );
	if( fp == NULL ) { fprintf( stderr, "create table error: cannot create data table file %s\n", tablename ); exit( 1 ); }
	
	/* check field names and generate field name header.. */
	error = 0;
	for( ; argi < argc; argi++ ) {
		if( !isalpha( (int) argv[argi][0] ) && argv[argi][0] != '_' ) {
			fprintf( stderr, "create table error: field name must begin with an alpha char (%s)\n", argv[argi] );
			error = 1;
			}
		for( i = 0; argv[argi][i] != '\0'; i++ ) {
			if( !isalnum( (int) argv[argi][i] ) && argv[argi][i] != '_' ) {
				fprintf( stderr, "create table error: invalid field name (%s)\n", argv[argi] ); 
				error = 1;
				}
			}
		fprintf( fp, "%s%c", argv[argi], SHSQL_delim );
		}
	fprintf( fp, "\n" );

	fclose( fp );
	if( error ) {
		unlink( filename );
		exit( 1 );
		}
	fprintf( stderr, "table %s created in directory %s/data\n", tablename, SHSQL_projdir );
	exit( 0 );
	}

if( objtype == INDEX ) {
	/* create index [type=xxx] on tablename fieldname1 .. fieldnameN */

	if( argc < 5 ) { fprintf( stderr, "create index error: not enough args\n" ); exit( 1 ); }
	strcpy( ixtypestr, "standard" );
	if( strnicmp( argv[ argi ], "type=", 5 )==0 ) {
		strcpy( ixtypestr, &argv[argi][5] );
		argi++;
		}
	else if( stricmp( argv[argi], "type" )== 0 && strcmp( argv[argi+1], "=" )==0 ) {
		argi+=2;
		strcpy( ixtypestr, argv[argi] );
		argi++;
		}

	for( i = 0; ixtypestr[i] != '\0'; i++ ) ixtypestr[i] = tolower( ixtypestr[i] );

	if( !GL_smember( ixtypestr, "standard direct word combinedword combined" ))
		{ fprintf( stderr, "create index error: unrecognized index type\n" ); exit( 1 ); }
		
	if( stricmp( argv[ argi ], "on" )!=0 && stricmp( argv[ argi ], "later" )!= 0 ) { 
		fprintf( stderr, "create index note: '%s' ignored\n", argv[argi] ); 
		argi++; 
		}
	laterflag = 0;
	if( stricmp( argv[ argi ], "later" )==0 ) { laterflag = 1; argi++; }
	if( stricmp( argv[ argi ], "on" )!=0 ) { fprintf( stderr, "create index error: 'on' expected\n" ); exit( 1 ); }
	argi++;
	strcpy( tablename, argv[argi] );
	argi++;

	if( argi >= argc ) { fprintf( stderr, "create index error: one or more fieldnames expected\n" ); exit( 1 ); }

	if( strnicmp( ixtypestr, "combined", 8 )==0 ) {
		/* build up ixtypestr like this:  combinedword,field2,field3 */
		strcat( ixtypestr, "," );
		/* skip primary fieldname (will be picked up below).. */
		for( i = argi+1; i < argc; i++ ) {
			strcat( ixtypestr, argv[i] );
			strcat( ixtypestr, "," );
			}
		}

	numflag = 0;

	/* verify that tablename is legit.. added scg 2/24/04 */
	stat = SHSQL_loadfieldmap( tablename );
	if( stat != 0 ) { fprintf( stderr, "create index error: table (%s) not found\n", tablename ); exit( 1 ); }
	ntablefields = fieldmap( "" );

	for( ; argi < argc; argi++ ) {

		if( numflag ) {
			argi += (numflag - 1 );
			numflag = 0;
			continue;
			}

		/* see if subsequent token indicates special ordering.. */
		if( argi+1 < argc ) {
			if( strnicmp( argv[argi+1], "order=num", 9 ) == 0 ) numflag = 1;
			else if( stricmp( argv[argi+1], "order" )==0 && (argi+2) < argc ) {
				if( strcmp( argv[argi+2], "=" )==0 && strnicmp( argv[argi+3], "num", 3 )==0 ) numflag = 3;
				}
			}
		

		/* verify that fieldname is legit.. scg 2/24/04, 3/4/04 */
		for( i = 0; i < ntablefields; i++ ) if( strcmp( argv[ argi ], TDH_fieldn( i ) ) == 0 ) break;
		if( i == ntablefields ) { 
			fprintf( stderr, "create index error: field (%s) not found in table %s\n", argv[ argi ], tablename ); 
			exit( 1 ); 
			}


		/* now numflag will be set (or not) for field argv[ argi ] .... */

		if( GL_member( tablename[0], "/." )) {
			if( SHSQL_bin[0] == '\0' ) sprintf( buf, "buildix %s %s 3 %s %s", 
				tablename, argv[argi], ixtypestr, (numflag)?"-t num":"" );
			else sprintf( buf, "%s/buildix %s %s 3 %s %s", 
				SHSQL_bin, tablename, argv[argi], ixtypestr, (numflag)?"-t num":"");

			system( buf );
			if( strnicmp( ixtypestr, "combined", 8 )==0 ) break; /* scg 12/6/04  */
									    /* all fields are done at once w/ these types */
			continue;
			}


		strcpy( fakename, tablename );
		for( i = 0; fakename[i] != '\0'; i++ ) if( fakename[i] == '/' ) fakename[i] = '!';
		sprintf( buf, "%s/indexes/%s.%s.2", SHSQL_projdir, fakename, argv[argi] );
		fp = fopen( buf, "w" );
		if( fp == NULL ) { fprintf( stderr, "create index error: cannot create index file %s\n", buf ); exit( 1 ); }
		fprintf( fp, "! index-type: %s sort-type: %s\n", ixtypestr, (numflag)?"num":"alpha" );
		fclose( fp );
		if( strnicmp( ixtypestr, "combined", 8 )==0 ) break; /* all fields are done at once w/ these types */
		}

	if( ! GL_member( tablename[0], "/." ) && !laterflag ) {
		if( SHSQL_bin[0] == '\0' ) sprintf( buf, "tabmaint -i %s", tablename );
		else sprintf( buf, "%s/tabmaint -i %s", SHSQL_bin, tablename );
		/* fprintf( stderr, "shsql_create is invoking: %s\n", buf ); */
		system( buf );
		}
	if( laterflag ) fprintf( stderr, "Index(es) to be built LATER via a 'create index' or 'maintain' command\n" );

	exit( 0 );
	}
	
fprintf( stderr, "Not yet implemented\n" );
exit( 1 );
}


