/*
 * Copyright (c) 2003, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the Contiki desktop OS.
 *
 * $Id: shell.c,v 1.3 2005/05/08 10:39:08 oliverschmidt Exp $
 *
 */

#include "program-handler.h"
#include "loader.h"
#include "cfs.h"
#include "uip.h"
#include "uip_arp.h"
#include "resolv.h"

#include "shell.h"

#include <string.h>

static char showingdir = 0;
static struct cfs_dir dir;
static unsigned int totsize;

struct ptentry {
  char c1;
  char c2;
  void (* pfunc)(char *str);
};

/*-----------------------------------------------------------------------------------*/
static void
parse(register char *str, struct ptentry *t)
{
  register struct ptentry *p;
  char *sstr;

  sstr = str;
  
  /* Loop over the parse table entries in t in order to find one that
     matches the first character in str. */
  for(p = t; p->c1 != 0; ++p) {
    if(*str == p->c1 || *str == p->c2) {
      /* Skip rest of the characters up to the first space. */
      while(*str != ' ') {
	++str;
      }

      /* Skip all spaces.*/
      while(*str == ' ') {
	++str;
      }

      /* Call parse table entry function and return. */
      p->pfunc(str);
      return;
    }
  }

  /* Did not find matching entry in parse table. We just call the
     default handler supplied by the caller and return. */
  p->pfunc(str);
}
/*-----------------------------------------------------------------------------------*/
static void
inttostr(register char *str, unsigned int i)
{
  str[0] = '0' + i / 100;
  if(str[0] == '0') {
    str[0] = ' ';
  }
  str[1] = '0' + (i / 10) % 10;
  if(str[0] == ' ' && str[1] == '0') {
    str[1] = ' ';
  }
  str[2] = '0' + i % 10;
  str[3] = ' ';
  str[4] = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
processes(char *str)
{
  static char idstr[5];
  struct ek_proc *p;

  shell_output("Processes:", "");
  /* Step through each possible process ID and see if there is a
     matching process. */
  for(p = EK_PROCS(); p != NULL; p = p->next) {
    inttostr(idstr, p->id);
    shell_output(idstr, (char *)p->name);
  }
}
/*-----------------------------------------------------------------------------------*/
static char *
nullterminate(char *str)
{
  char *nt;

  /* Nullterminate string. Start with finding newline character. */
  for(nt = str; *nt != '\r' &&
	*nt != '\n'; ++nt);

  /* Replace newline with a null char. */
  *nt = 0;

  /* Remove trailing spaces. */
  while(nt > str && *(nt - 1) == ' ') {
    *(nt - 1) = 0;
    --nt;
  }
  
  /* Return pointer to null char. */
  return nt;
}
/*-----------------------------------------------------------------------------------*/
static void
runfile(char *str)
{
  nullterminate(str);

  if(strlen(str) > 0) {
    /* Call loader function. */
    program_handler_load(str, NULL);
    shell_output("Starting program ", str);  
  } else {
    shell_output("Must supply a program name", "");  
  }
}
/*-----------------------------------------------------------------------------------*/
static void
execfile(char *str)
{
  runfile(str);
  shell_quit(NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
killproc(char *str)
{
  char procnum, j, c;
  char procstr[5];

  nullterminate(str);
  
  procnum = 0;
  
  for(j = 0; j < 4; ++j) {
    c = str[j];
    if(c >= '0' && c <= '9') {
      procnum = procnum * 10 + (str[j] - '0');
    } else {
      break;
    }
  }
  if(procnum != 0) {
    inttostr(procstr, procnum);
    shell_output("Killing process ", procstr);
    ek_post(procnum, EK_EVENT_REQUEST_EXIT, NULL);
  } else {
    shell_output("Invalid process number", "");
  }
  
}
/*-----------------------------------------------------------------------------------*/
static void
help(char *str)
{
  shell_output("Available commands:", "");
  shell_output("run  - start program", "");
  shell_output("exec - start program & exit shell", "");  
  shell_output("ps   - show processes", "");
  shell_output("kill - kill process", "");
  shell_output("ls   - display directory", "");
  shell_output("quit - quit shell", "");
  shell_output("?    - show this help", "");      
}
/*-----------------------------------------------------------------------------------*/
static void
directory(char *str)
{
  if(cfs_opendir(&dir, ".") != 0) {
    shell_output("Cannot open directory", "");
    showingdir = 0;
  } else {
    shell_output("Disk directory:", "");
    showingdir = 1;
    totsize = 0;
    ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL);
  }
  
}
/*-----------------------------------------------------------------------------------*/
static void
none(char *str)
{
}
/*-----------------------------------------------------------------------------------*/
static struct ptentry configparsetab[] =
  {{'e', 'E', execfile},
   {'r', 'R', runfile},
   {'k', 'K', killproc},   
   {'p', 'P', processes},
   {'l', 'L', directory},
   {'q', 'Q', shell_quit},
   {'h', '?', help},

   /* Default action */
   {0,   0,   none}};
/*-----------------------------------------------------------------------------------*/
void
shell_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
void
shell_start(void)
{
  showingdir = 0;
  shell_output("Contiki command shell", "");
  shell_output("Type '?' and return for help", "");  
  shell_prompt("contiki> "); 
}
/*-----------------------------------------------------------------------------------*/
void
shell_input(char *cmd)
{
  if(showingdir != 0) {
    showingdir = 0;
    shell_output("Directory stopped", "");
    cfs_closedir(&dir);
  }
  parse(cmd, configparsetab);
  if(showingdir == 0) {
    shell_prompt("contiki> ");
  }
}
/*-----------------------------------------------------------------------------------*/
void
shell_eventhandler(ek_event_t ev, ek_data_t data)
{
  static struct cfs_dirent dirent;
  static char size[10];

  if(ev == EK_EVENT_CONTINUE) {
    if(showingdir != 0) {
      if(cfs_readdir(&dir, &dirent) != 0) {
	cfs_closedir(&dir);
	showingdir = 0;
	inttostr(size, totsize);
	shell_output("Total number of blocks: ", size);
	shell_prompt("contiki> ");
      } else {
	totsize += dirent.size;
	inttostr(size, dirent.size);
	shell_output(size, dirent.name);
	ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL);
      }
    }
  }
}
/*-----------------------------------------------------------------------------------*/
