#include <alloca.h>
#include <newt.h>
#include <sys/wait.h>
#include <malloc.h>
#include <strings.h>
#include <unistd.h>

#include "config.h"
#include "install.h"
#include "kickstart.h"
#include "log.h"

static int runConfigTool(char * rootPath,
			 char * tool, int argc, char ** inargv) {
    int childpid;
    int status;
    char ** argv = NULL;

    if (inargv) {
	argv = alloca(sizeof(*argv) * (argc + 1));
	memcpy(argv, inargv, sizeof(*argv) * argc);
	argv[argc] = NULL;
	argv[0] = tool;
    }

    logMessage("running %s", tool);
    newtSuspend();

    if (!(childpid = fork())) {
	if (!testing) chroot(rootPath);
	chdir("/");

	if (argv)
	    execv(argv[0], argv);
	else
	    execl(tool, tool, NULL);
	exit(2);
    } 

    waitpid(childpid, &status, 0);
    newtResume();
    if (WIFEXITED(status)) {
	if (WEXITSTATUS(status) == 1) {
	    logMessage("    tool canceled");
	    return INST_CANCEL;
	} else if (WEXITSTATUS(status) == 0) {
	    return 0;
	}
    }

    logMessage("    tool failed");

    return INST_ERROR;
}

int timeConfig(char * rootPath) {
    char ** argv; 
    int argc;
    char * otherArgv[] = { "timeconfig", 
#if 0    
    			   "--back", /* We do not ship newt 0.3 yet */
#endif    			   
    			   NULL };

    if (kickstart && !ksGetCommand(KS_CMD_TIMEZONE, NULL, &argc, &argv)) {
	return runConfigTool(rootPath, "/usr/sbin/timeconfig", argc, argv);
    }

    return runConfigTool(rootPath, "/usr/sbin/timeconfig", 2, otherArgv);
}

int servicesConfig(char * rootPath) {
    char * otherArgv[] = { "/usr/sbin/ntsysv",
#if 0    
    			   "--back", /* We do not ship newt 0.3 yet */
#endif
    			   NULL };

    return runConfigTool(rootPath, "/usr/sbin/ntsysv", 2, otherArgv);
}

int mouseConfig(char * rootPath) {
    char ** argv, **kargv; 
    int argc;
    int i;
    int shift;
    
    if (!kickstart || ksGetCommand(KS_CMD_MOUSE, NULL, &argc, &argv)) {
	/* no options, or in normal mode */
	argc = 1;
	argv = alloca(sizeof(*argv));
	argv[0] = alloca(sizeof("mouse")+1);
	strcpy(argv[0],"mouse");
    }	

    /* add --kickstart and --expert options */
    shift = 0;
    if (kickstart)
	shift++;
    if (expert)
	shift++;
    
    kargv = alloca(sizeof(*argv) * (argc + shift));
    memcpy(kargv, argv, sizeof(*argv) * argc);
    for (i=argc+shift-1; i>shift; i--)
	kargv[i]=kargv[i-shift];

    i = 1;
    if (kickstart) {
	kargv[i] = "--kickstart";
	i++;
    }
    if (expert) {
	kargv[i] = "--expert";
	kargv[i] = "--noprobe";
	i++;
    }

    argc += shift;
    return runConfigTool(rootPath, "/usr/sbin/mouseconfig", argc, kargv);
}

int xfree86Config(char * rootPath, char *mode) {
    char **argv, **kargv;
    int argc;
    int i;
    int shift;

    argv  = NULL;
    kargv = NULL;
    if (!kickstart || ksGetCommand(KS_CMD_XCONFIG, argv, &argc, &argv)) {
	/* they didnt specify anything, or in normal mode */
	argc=1;
	argv=alloca(sizeof(*argv));
	argv[0]=alloca(strlen("xconfig"+1));
	strcpy(argv[0],"xconfig");
    }
    
    /* make commandline, add mode and --kickstart, and maybe --expert */
    shift = 1;
    if (expert)
	shift++;
    if (kickstart)
	shift++;

    kargv = alloca(sizeof(*argv) * (argc + shift));
    memcpy(kargv, argv, sizeof(*argv) * argc);
    for (i=argc+shift-1; i>shift; i--)
	kargv[i]=kargv[i-shift];

    i = 1;
    if (kickstart) {
	kargv[i] = "--kickstart";
	i++;
    }
    if (expert) {
	kargv[i] = "--expert";
	i++;
    }

    kargv[i] = alloca(strlen(mode)+1);
    strcpy(kargv[i],mode);
    i++;
    
    argc+=shift;
	
    return runConfigTool(rootPath, "/usr/X11R6/bin/Xconfigurator",argc, kargv);
}

void configPCMCIA(char * rootPath, char * pcic) {
    FILE * f;
    char * path;

    if (testing) return;

    path = alloca(strlen(rootPath) + 30);
    sprintf(path, "%s/etc/sysconfig/pcmcia", rootPath);

    f = fopen(path, "w");
    if (pcic) {
	fprintf(f, "PCMCIA=yes\n");
	fprintf(f, "PCIC=%s\n", pcic);
    } else {
	fprintf(f, "PCMCIA=no\n");
	fprintf(f, "PCIC=\n");
    }

    fprintf(f, "PCIC_OPTS=\nCORE_OPTS=\n");

    fclose(f);
}
