/*  Copyright 1997-2002,2005-2009 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Mtools is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
 *
 * mainloop.c
 * Iterating over all the command line parameters, and matching patterns
 * where needed
 */

#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "vfat.h"
#include "fs.h"
#include "mainloop.h"
#include "plain_io.h"
#include "file.h"
#include "file_name.h"


/* Fix the info in the MCWD file to be a proper directory name.
 * Always has a leading separator.  Never has a trailing separator
 * (unless it is the path itself).  */

static const char *fix_mcwd(char *ans)
{
	FILE *fp;
	char *s;
	char buf[MAX_PATH];

	fp = open_mcwd("r");
	if(!fp || !fgets(buf, MAX_PATH, fp)) {
		if(fp)
			fclose(fp);
		ans[0] = get_default_drive();
		strcpy(ans+1, ":/");
		return ans;
	}

	buf[strlen(buf) -1] = '\0';
	fclose(fp);
					/* drive letter present? */
	s = buf;
	if (buf[0] && buf[1] == ':') {
		memcpy(ans, buf, 2);
		ans[2] = '\0';
		s = &buf[2];
	} else {
		ans[0] = get_default_drive();
		strcpy(ans+1, ":");
	}
			/* add a leading separator */
	if (*s != '/' && *s != '\\') {
		strcat(ans, "/");
		strcat(ans, s);
	} else
		strcat(ans, s);

#if 0
					/* translate to upper case */
	for (s = ans; *s; ++s) {
		*s = ch_toupper(*s);
		if (*s == '\\')
			*s = '/';
	}
#endif
					/* if only drive, colon, & separator */
	if (strlen(ans) == 3)
		return(ans);
					/* zap the trailing separator */
	if (*--s == '/')
		*s = '\0';
	return ans;
}

int unix_dir_loop(Stream_t *Stream, MainParam_t *mp);
int unix_loop(Stream_t *Stream UNUSEDP, MainParam_t *mp, char *arg,
	      int follow_dir_link);

static int _unix_loop(Stream_t *Dir, MainParam_t *mp,
		      const char *filename UNUSEDP)
{
	return unix_dir_loop(Dir, mp);
}

int unix_loop(Stream_t *Stream UNUSEDP, MainParam_t *mp,
	      char *arg, int follow_dir_link)
{
	int ret;
	int isdir=0;
	size_t unixNameLength;

	mp->File = NULL;
	mp->direntry = NULL;
	unixNameLength = strlen(arg);
	if(unixNameLength > 1 && arg[unixNameLength-1] == '/') {
	    /* names ending in slash, and having at least two characters */
	    char *name = strdup(arg);
	    name[unixNameLength-1]='\0';
	    mp->unixSourceName = name;
	} else {
	    mp->unixSourceName = arg;
	}
	/*	mp->dir.attr = ATTR_ARCHIVE;*/
	mp->loop = _unix_loop;
	if((mp->lookupflags & DO_OPEN)){
		mp->File = SimpleFileOpen(0, 0, arg, O_RDONLY, 0, 0, 0, 0);
		if(!mp->File){
			perror(arg);
#if 0
			tmp = _basename(arg);
			strncpy(mp->filename, tmp, VBUFSIZE);
			mp->filename[VBUFSIZE-1] = '\0';
#endif
			return ERROR_ONE;
		}
		GET_DATA(mp->File, 0, 0, &isdir, 0);
		if(isdir) {
#if !defined(__EMX__) && !defined(OS_mingw32msvc)
			struct MT_STAT buf;
#endif

			FREE(&mp->File);
#if !defined(__EMX__) && !defined(OS_mingw32msvc)
			if(!follow_dir_link &&
			   MT_LSTAT(arg, &buf) == 0 &&
			   S_ISLNK(buf.st_mode)) {
				/* skip links to directories in order to avoid
				 * infinite loops */
				fprintf(stderr,
					"skipping directory symlink %s\n",
					arg);
				return 0;
			}
#endif
			if(! (mp->lookupflags & ACCEPT_DIR))
				return 0;
			mp->File = OpenDir(arg);
		}
	}

	if(isdir)
		ret = mp->dirCallback(0, mp);
	else
		ret = mp->unixcallback(mp);
	FREE(&mp->File);
	return ret;
}


int isSpecial(const char *name)
{
	if(name[0] == '\0')
		return 1;
	if(!strcmp(name,"."))
		return 1;
	if(!strcmp(name,".."))
		return 1;
	return 0;
}

#ifdef HAVE_WCHAR_H
int isSpecialW(const wchar_t *name)
{
	if(name[0] == '\0')
		return 1;
	if(!wcscmp(name,L"."))
		return 1;
	if(!wcscmp(name,L".."))
		return 1;
	return 0;
}
#endif

static int checkForDot(int lookupflags, const wchar_t *name)
{
	return (lookupflags & NO_DOTS) && isSpecialW(name);
}


typedef struct lookupState_t {
	Stream_t *container;
	int nbContainers;
	Stream_t *Dir;
	int nbDirs;
	const char *filename;
} lookupState_t;

static int isUniqueTarget(const char *name)
{
	return name && strcmp(name, "-");
}

static int handle_leaf(direntry_t *direntry, MainParam_t *mp,
		       lookupState_t *lookupState)
{
	Stream_t *MyFile=0;
	int ret;

	if(got_signal)
		return ERROR_ONE;
	if(lookupState) {
		/* we are looking for a "target" file */
		switch(lookupState->nbDirs) {
			case 0: /* no directory yet, open it */
				lookupState->Dir = OpenFileByDirentry(direntry);
				lookupState->nbDirs++;
				/* dump the container, we have
				 * better now */
				FREE(&lookupState->container);
				return 0;
			case 1: /* we have already a directory */
				FREE(&lookupState->Dir);
				fprintf(stderr,"Ambiguous\n");
				return STOP_NOW | ERROR_ONE;
			default:
				return STOP_NOW | ERROR_ONE;
		}
	}

	mp->direntry = direntry;
	if(IS_DIR(direntry)) {
		if(mp->lookupflags & (DO_OPEN | DO_OPEN_DIRS))
			MyFile = mp->File = OpenFileByDirentry(direntry);
		ret = mp->dirCallback(direntry, mp);
	} else {
		if(mp->lookupflags & DO_OPEN)
			MyFile = mp->File = OpenFileByDirentry(direntry);
		ret = mp->callback(direntry, mp);
	}
	FREE(&MyFile);
	if(isUniqueTarget(mp->targetName))
		ret |= STOP_NOW;
	return ret;
}

static int _dos_loop(Stream_t *Dir, MainParam_t *mp, const char *filename)
{
	Stream_t *MyFile=0;
	direntry_t entry;
	int ret;
	int r;

	ret = 0;
	r=0;
	initializeDirentry(&entry, Dir);
	while(!got_signal &&
	      (r=vfat_lookup_zt(&entry, filename,
				mp->lookupflags,
				mp->shortname.data, mp->shortname.len,
				mp->longname.data, mp->longname.len)) == 0 ){
		mp->File = NULL;
		if(!checkForDot(mp->lookupflags,entry.name)) {
			MyFile = 0;
			if((mp->lookupflags & DO_OPEN) ||
			   (IS_DIR(&entry) &&
			    (mp->lookupflags & DO_OPEN_DIRS))) {
				MyFile = mp->File = OpenFileByDirentry(&entry);
			}
			if(got_signal)
				break;
			mp->direntry = &entry;
			if(IS_DIR(&entry))
				ret |= mp->dirCallback(&entry,mp);
			else
				ret |= mp->callback(&entry, mp);
			FREE(&MyFile);
		}
		if (fat_error(Dir))
			ret |= ERROR_ONE;
		if(mp->fast_quit && (ret & ERROR_ONE))
			break;
	}
	if (r == -2)
	    return ERROR_ONE;
	if(got_signal)
		ret |= ERROR_ONE;
	return ret;
}

static int recurs_dos_loop(MainParam_t *mp, const char *filename0,
			   const char *filename1,
			   lookupState_t *lookupState)
{
	/* Dir is de-allocated by the same entity which allocated it */
	const char *ptr;
	direntry_t entry;
	size_t length;
	int lookupflags;
	int ret;
	int have_one;
	int doing_mcwd;
	int r;

	while(1) {
		/* strip dots and / */
		if(!strncmp(filename0,"./", 2)) {
			filename0 += 2;
			continue;
		}
		if(!strcmp(filename0,".") && filename1) {
			filename0 ++;
			continue;
		}
		if(filename0[0] == '/') {
			filename0++;
			continue;
		}
		if(!filename0[0]) {
			if(!filename1)
				break;
			filename0 = filename1;
			filename1 = 0;
			continue;
		}
		break;
	}

	if(!strncmp(filename0,"../", 3) ||
	   (!strcmp(filename0, "..") && filename1)) {
		/* up one level */
		mp->File = getDirentry(mp->File)->Dir;
		return recurs_dos_loop(mp, filename0+2, filename1, lookupState);
	}

	doing_mcwd = !!filename1;

	ptr = strchr(filename0, '/');
	if(!ptr) {
		length = strlen(filename0);
		ptr = filename1;
		filename1 = 0;
	} else {
		length = ptrdiff(ptr, filename0);
		ptr++;
	}
	if(!ptr) {
		if(mp->lookupflags & OPEN_PARENT) {
			mp->targetName = filename0;
			ret = handle_leaf(getDirentry(mp->File), mp,
					  lookupState);
			mp->targetName = 0;
			return ret;
		}

		if(!strcmp(filename0, ".") || !filename0[0]) {
			return handle_leaf(getDirentry(mp->File),
					   mp, lookupState);
		}

		if(!strcmp(filename0, "..")) {
			return handle_leaf(getParent(getDirentry(mp->File)), mp,
					   lookupState);
		}

		lookupflags = mp->lookupflags;

		if(lookupState) {
			lookupState->filename = filename0;
			if(lookupState->nbContainers + lookupState->nbDirs > 0){
				/* we have already one target, don't bother
				 * with this one. */
				FREE(&lookupState->container);
			} else {
				/* no match yet.  Remember this container for
				 * later use */
				lookupState->container = COPY(mp->File);
			}
			lookupState->nbContainers++;
		}
	} else
		lookupflags = ACCEPT_DIR | DO_OPEN | NO_DOTS;

	ret = 0;
	r = 0;
	have_one = 0;
	initializeDirentry(&entry, mp->File);
	while(!(ret & STOP_NOW) &&
	      !got_signal &&
	      (r=vfat_lookup(&entry, filename0, length,
			     lookupflags | NO_MSG,
			     mp->shortname.data, mp->shortname.len,
			     mp->longname.data, mp->longname.len)) == 0 ){
		if(checkForDot(lookupflags, entry.name))
			/* while following the path, ignore the
			 * special entries if they were not
			 * explicitly given */
			continue;
		have_one = 1;
		if(ptr) {
			Stream_t *SubDir;
			SubDir = mp->File = OpenFileByDirentry(&entry);
			ret |= recurs_dos_loop(mp, ptr, filename1, lookupState);
			FREE(&SubDir);
		} else {
			ret |= handle_leaf(&entry, mp, lookupState);
			if(isUniqueTarget(mp->targetName))
				return ret | STOP_NOW;
		}
		if(doing_mcwd)
			break;
	}
	if (r == -2)
		return ERROR_ONE;
	if(got_signal)
		return ret | ERROR_ONE;
	if(doing_mcwd && !have_one)
		return NO_CWD;
	return ret;
}

static int common_dos_loop(MainParam_t *mp, const char *pathname,
			   lookupState_t *lookupState, int open_mode)

{
	Stream_t *RootDir;
	const char *cwd;
	char drive;

	int ret;
	mp->loop = _dos_loop;

	drive='\0';
	cwd = "";
	if(*pathname && pathname[1] == ':') {
		drive = ch_toupper(*pathname);
		pathname += 2;
		if(mp->mcwd[0] == drive)
			cwd = mp->mcwd+2;
	} else if(mp->mcwd[0]) {
		drive = mp->mcwd[0];
		cwd = mp->mcwd+2;
	} else {
		drive = get_default_drive();
	}

	if(*pathname=='/') /* absolute path name */
		cwd = "";

	RootDir = mp->File = open_root_dir(drive, open_mode, NULL);
	if(!mp->File)
		return ERROR_ONE;

	ret = recurs_dos_loop(mp, cwd, pathname, lookupState);
	if(ret & NO_CWD) {
		/* no CWD */
		*mp->mcwd = '\0';
		unlink_mcwd();
		ret = recurs_dos_loop(mp, "", pathname, lookupState);
	}
	FREE(&RootDir);
	return ret;
}

static int dos_loop(MainParam_t *mp, const char *arg)
{
	return common_dos_loop(mp, arg, 0, mp->openflags);
}


static int dos_target_lookup(MainParam_t *mp, const char *arg)
{
	lookupState_t lookupState;
	int ret;
	int lookupflags;

	lookupState.nbDirs = 0;
	lookupState.Dir = 0;
	lookupState.nbContainers = 0;
	lookupState.container = 0;

	lookupflags = mp->lookupflags;
	mp->lookupflags = DO_OPEN | ACCEPT_DIR;
	ret = common_dos_loop(mp, arg, &lookupState, O_RDWR);
	mp->lookupflags = lookupflags;
	if(ret & ERROR_ONE)
		return ret;

	if(lookupState.nbDirs) {
		mp->targetName = 0;
		mp->targetDir = lookupState.Dir;
		FREE(&lookupState.container); /* container no longer needed */
		return ret;
	}

	switch(lookupState.nbContainers) {
		case 0:
			/* no match */
			fprintf(stderr,"%s: no match for target\n", arg);
			return MISSED_ONE;
		case 1:
			mp->targetName = strdup(lookupState.filename);
			mp->targetDir = lookupState.container;
			return ret;
		default:
			/* too much */
			fprintf(stderr, "Ambiguous %s\n", arg);
			return ERROR_ONE;
	}
}

/*
 * Is target a Unix directory
 * -1 error occured
 * 0 regular file
 * 1 directory
 */
static int unix_is_dir(const char *name)
{
	struct stat buf;
	if(stat(name, &buf) < 0)
		return -1;
	else
		return 1 && S_ISDIR(buf.st_mode);
}

static int unix_target_lookup(MainParam_t *mp, const char *arg)
{
	char *ptr;
	mp->unixTarget = strdup(arg);
	/* try complete filename */
	if(access(mp->unixTarget, F_OK) == 0) {
		switch(unix_is_dir(mp->unixTarget)) {
		case -1:
			return ERROR_ONE;
		case 0:
			mp->targetName="";
			break;
		}
		return GOT_ONE;
	}
	ptr = strrchr(mp->unixTarget, '/');
	if(!ptr) {
		mp->targetName = mp->unixTarget;
		mp->unixTarget = strdup(".");
		return GOT_ONE;
	} else {
		*ptr = '\0';
		mp->targetName = ptr+1;
		return GOT_ONE;
	}
}

int target_lookup(MainParam_t *mp, const char *arg)
{
	if((mp->lookupflags & NO_UNIX) || (arg[0] && arg[1] == ':' ))
		return dos_target_lookup(mp, arg);
	else
		return unix_target_lookup(mp, arg);
}

int main_loop(MainParam_t *mp, char **argv, int argc)
{
	int i;
	int ret, Bret;

	Bret = 0;

	if(argc != 1 && mp->targetName) {
		fprintf(stderr,
			"Several file names given, but last argument (%s) not a directory\n", mp->targetName);
		FREE(&mp->targetDir);
		return 1;
	}

	for (i = 0; i < argc; i++) {
		if ( got_signal )
			break;
		mp->originalArg = argv[i];
		mp->basenameHasWildcard = strpbrk(_basename(mp->originalArg),
						  "*[?") != 0;
		if (mp->unixcallback && (!argv[i][0]
#ifdef OS_mingw32msvc
/* On Windows, support only the command-line image drive. */
                                         || argv[i][0] != ':'
#endif
                                         || argv[i][1] != ':' ))
			ret = unix_loop(0, mp, argv[i], 1);
		else
			ret = dos_loop(mp, argv[i]);

		if (! (ret & (GOT_ONE | ERROR_ONE)) ) {
			/* one argument was unmatched */
			fprintf(stderr, "%s: File \"%s\" not found\n",
				progname, argv[i]);
			ret |= ERROR_ONE;
		}
		Bret |= ret;
		if(mp->fast_quit && (Bret & (MISSED_ONE | ERROR_ONE)))
			break;
	}
	FREE(&mp->targetDir);
	if(Bret & ERROR_ONE)
		return 1;
	if ((Bret & GOT_ONE) && ( Bret & MISSED_ONE))
		return 2;
	if (Bret & MISSED_ONE)
		return 1;
	return 0;
}

static int dispatchToFile(direntry_t *entry, MainParam_t *mp)
{
	if(entry)
		return mp->callback(entry, mp);
	else
		return mp->unixcallback(mp);
}


void init_mp(MainParam_t *mp)
{
	fix_mcwd(mp->mcwd);
	mp->openflags = O_RDONLY;
	mp->targetName = 0;
	mp->targetDir = 0;
	mp->unixTarget = 0;
	mp->dirCallback = dispatchToFile;
	mp->unixcallback = NULL;
	mp->shortname.data = mp->longname.data = 0;
	mp->shortname.len = mp->longname.len = 0;
	mp->File = 0;
	mp->fast_quit = 0;
}

const char *mpGetBasename(MainParam_t *mp)
{
	if(mp->direntry) {
		wchar_to_native(mp->direntry->name, mp->targetBuffer,
				MAX_VNAMELEN+1, sizeof(mp->targetBuffer));
		return mp->targetBuffer;
	} else
		return _basename(mp->unixSourceName);
}

void mpPrintFilename(FILE *fp, MainParam_t *mp)
{
	if(mp->direntry)
		fprintPwd(fp, mp->direntry, 0);
	else
		fprintf(fp,"%s",mp->originalArg);
}

const char *mpPickTargetName(MainParam_t *mp)
{
	/* picks the target name: either the one explicitly given by the
	 * user, or the same as the source */
	if(mp->targetName)
		return mp->targetName;
	else
		return mpGetBasename(mp);
}

char *mpBuildUnixFilename(MainParam_t *mp)
{
	const char *target;
	char *ret;
	char *tmp;

	target = mpPickTargetName(mp);
	ret = malloc(strlen(mp->unixTarget) + 2 + strlen(target));
	if(!ret)
		return 0;
	strcpy(ret, mp->unixTarget);
	if(*target) {
		/* fix for 'mcopy -n x:file existingfile' -- H. Lermen 980816 */
		if(!mp->targetName && !mp->targetDir && !unix_is_dir(ret))
			return ret;
		strcat(ret, "/");
		if(!strcmp(target, ".")) {
		  target="DOT";
		} else if(!strcmp(target, "..")) {
		  target="DOTDOT";
		}
		while( (tmp=strchr(target, '/')) ) {
		  strncat(ret, target, ptrdiff(tmp,target));
		  strcat(ret, "\\");
		  target=tmp+1;
		}
		strcat(ret, target);
	}
	return ret;
}
