//file=bsh2_inclass.c
//author=jhd 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

//accept up to 16 command-line arguments
#define MAXARG 16

//allow up to 64 environment variables
#define MAXENV 64

//keep the last 500 commands in history
#define HISTSIZE 500

//accept up to 1024 bytes in one command
#define MAXLINE 1024


static char **parseCmd(char cmdLine[]) {
  int k;
  char **cmdArg, *ptr;
  int i;
  printf("Now in bsh2 parseCmd.\nDECLARE VARIABLE k and get local address: \n\nThe the address of declared variable, k, is: \n%p\n\n\n",&k);

  printf("DECLARE VARIABLE cmdArg, char **cmdArg, is: \n%p\n\n\n",&cmdArg);

  //(MAXARG + 1) because the list must be terminated by a NULL ptr

  printf("USE MALLOC (first time):\n\n"); 

  cmdArg = (char **) malloc(sizeof(char *) * (MAXARG + 1));
  if (cmdArg == NULL) {
	perror("parseCmd: cmdArg is NULL\n");
	exit(1);
  } else {
    printf("  Malloc returned cmdArg pointer type **char which has: \n    addr: \n%p and \n    data (also a ptr) \n%p\n", &cmdArg, cmdArg); 
  } 
  for (i = 0; i <= MAXARG; i++) //note the equality
	cmdArg[i] = NULL;//jhd null the pointers
  

  i = 0;
  ptr = strsep(&cmdLine, " ");

  while (ptr != NULL) {
	// (strlen(ptr) + 1)



        printf("\n\nUSE MALLOC (repeatedly, at %d):\n\n",i); 
	cmdArg[i] = (char *) malloc(sizeof(char) * (strlen(ptr) + 1));
	if (cmdArg[i] == NULL) {
		perror("parseCmd: cmdArg[i] is NULL");
		exit(1);
	} else {
          printf("  Malloc returned cmdArg pointer type *char with len of each ptr which has i=%d: \n    addr: \n%p\n",i, &cmdArg[i]);
        } 
        strcpy(cmdArg[ i++ ], ptr);
        printf("     cmdArg[%d] data at next i=%d is now in string, use i-1: \n%s\n",i,i, cmdArg[i-1]);
        printf("     if it shows (null), ...because strcpy(cmdArg[ i++ ], ptr); was done...moved to next part before cp?\n"); 
	if (i == MAXARG)
      		break;
    	ptr = strsep(&cmdLine, " ");
  }


  printf("\n\n\n\nNow returning to main from parseCmd\n");
  return(cmdArg);
}




int main(int argc, char *argv[], char *envp[]) {
  char cmdLine[MAXLINE], **cmdArg;
  int status, i, debug, debug2, numEnvVar;
  pid_t pid;




  //make output page
  printf("\n\n\n1. Name:\n\n\n"); 

  printf("2. Data output by code:\n\n\n\n"); 

  printf("Now starting bsh2 main\n");


  //jhd count envp items not NULL 
  int k = 0;
  while (envp[k] != NULL){
     k++;
  }	
  numEnvVar = k-2;

  //jhd copy envp using MALLOC 	
  char** envList;
  envList = (char **) malloc(sizeof(char *) * (numEnvVar + 1));
  if (envList == NULL){
	perror("main: envList is NULL");
	exit(1);
  } else {
   printf("  Now will copy envp array ...data...\n");
  } 
  for (i = 0; i <= numEnvVar; i++) //note the equality
  	envList[i] = NULL;//jhd null the pointers
 


  printf("\n\n\n\nReady to process your cmd to .bsh2_inclass; choose setenv <var> <value> to see a sequence of items in cmdArg; then choose exit\n");


  //now loop to process incoming commands
  while (( 1 )) {

    printf("\n\n\nbsh> ");                      //prompt

    fgets(cmdLine, MAXLINE, stdin);       //get a line from keyboard

    cmdLine[strlen(cmdLine) - 1] = '\0';  //strip '\n'
                                          //jhd strlen replaces newline by null byte 
    cmdArg = parseCmd(cmdLine);
    printf("In main after call to parseCmd, \ncmdArg[0] returned is: \n%p, \ncmdArg[0] is: \n%s\n",cmdArg,cmdArg[0]);

    if (cmdArg[1] != NULL) printf("\ncmdArg[1] address is: \n%p, \ncmdARG[1] data string is: \n%s\n",&cmdArg[1],cmdArg[1]); 


    if (cmdArg[2] != NULL) printf("\ncmdArg[2] address is: \n%p, \ncmdARG[2] data string is: \n%s\n",&cmdArg[2],cmdArg[2]); 

    //built-in command exit
    if (strcmp(cmdArg[0], "exit") == 0) {
      //if (debug)
	printf("\n\nprocessing cmd exit and exiting\n");
      break;
    }
    

    //built-in command env
    else if (strcmp(cmdArg[0], "env") == 0) {
      printf("\nprocessing cmd env\n\n");
      k = 0;
      while(k < numEnvVar){
	//printf("%s %d %p\n", envList[k], k, &envList[k]);
        printf("Hello! envp[k]=%s k=%d numEnvVar=%d\n", envp[k], k, numEnvVar);
        k++;
      }
    }


    //built-in command setenv
    else if (strcmp(cmdArg[0], "setenv") == 0) {
       printf("\n\nprocessing cmd setenv var value\n\n");
 
    }

    		
    //built-in command unsetenv
    else if (strcmp(cmdArg[0], "unsetenv") == 0) {
    
    } 
    
    //built-in command cd
    else if (strcmp(cmdArg[0], "cd") == 0) {
    
    } 
    
    //built-in command history
    else if (strcmp(cmdArg[0], "history") == 0) {
    
    }
 
    //clean up before running the next command by doing free on both levels of cmdArg 
    printf("\nfreeing elements of cmdArg, then cmdArg\n\n"); 
    i = 0;
    while (cmdArg[i] != NULL)
      free( cmdArg[i++] );
    if (cmdArg != NULL) 
      free(cmdArg);
    
  }
  printf("\n\nout of while loop for commands\n");
  
 
  return 0;
}
