/* resister-stardata - A program to register stardata catalogues to 
 * astronomy programs data format.
 * Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009
 * Francisco García Claramonte <franciscomanuel.garcia@hispalinux.es>
 *
 *
 *  This program 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 
 *  MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
    #include <config.h>
#endif

 
#include <stdio.h>
#include <argp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>


#define SCRIPTS_DIR  	"/usr/lib/stardata-common/"
#define STARDATA_DIR 	"/usr/share/stardata/"
#define SHELL 		"sh"

const char *argp_program_version =
	"register-stardata 0.7";

static char doc[] =
	"register-stardata -- Install or remove stardata catalogues to the native\n\
format of astronomy software data formats.\n\
'action' = {install|remove},\n\
'stardata' is the dataset to update, or 'all' for all available catalogues,\n\
'program' is the software package data format to convert the datasets, or\n\
          'all' for all available astronomy packages.";

static char args_doc[] = 
	"<action> <stardata> <program>";

const char *argp_program_bug_address =
	"<franciscomanuel.garcia@hispalinux.es>";

static struct argp_option options[] = {
	{"quiet",'q', 0, 0,"Don't produce any output"},
 	{ 0 }
};


/* Used by main to communicate with parse_opt. */
struct arguments
{
	char *args[3];    
	int silent;
};




static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  /* Get the input argument from argp_parse, which we
     know is a pointer to our arguments structure. */
	struct arguments *arguments = state->input;

	switch (key)
	{
		case 'q': 
			arguments->silent = 1;
			break;
	  		
        	case ARGP_KEY_ARG:
      		if (state->arg_num >= 3)
		        argp_usage (state);
			arguments->args[state->arg_num] = arg;
			break;

		case ARGP_KEY_END:
			if (state->arg_num < 3)
        		argp_usage (state);
      			break;

	    default:
    		  return ARGP_ERR_UNKNOWN;
	}
  	return 0;
}


static struct argp argp = { 
	options, parse_opt, args_doc, doc 
};


int execute (char *program, char *action, char *stardata)
{
	char *path;
	int result;
	
	path = malloc(strlen(SHELL) + strlen(SCRIPTS_DIR)
	    + strlen(program) + strlen(action) + strlen(stardata) + 4);
	if (!path)
	  return 1;

	sprintf(path, "%s %s%s %s %s", SHELL, SCRIPTS_DIR, program,
				       action, stardata);
	result = system(path);
	free(path);
	return result;	  
}



int process(char *action, char *stardata, char *program) 
{
	DIR *dir;
	struct dirent *ep;

	int state = 0;

	char buffer[100];
	char *test_path = buffer;
	int test_ret;


	if (strcmp(program,"all")!=0) 
	  {
	    test_path = strcpy(test_path, SCRIPTS_DIR);
	    test_path = strcat(test_path, program);
	    if ((test_ret = access(test_path ,F_OK))!= 0)
	      return 3;
	  }

	if (strcmp(action,"remove") != 0 && strcmp(action,"install") != 0)
	    return 2;
	
	if (strcmp(stardata,"all")==0 && strcmp(program,"all")==0)
	    return 1;
	
	if (strcmp(stardata,"all")!=0 && strcmp(program,"all")!=0) 
	  {
	      state = execute(program, action, stardata);
	      return state;
	  }
	    

	if (strcmp(stardata,"all")!=0 && strcmp(program,"all")==0 )
	  {
	    //register <cataloge> <all>
	  	dir = opendir (SCRIPTS_DIR);
		if (dir != NULL)
    		{			    	
      			while ((ep = readdir (dir)))
		    		if ( strcmp(ep->d_name , ".")!=0 && strcmp(ep->d_name ,"..")!=0)
				  state = execute (ep->d_name, action, stardata);

      			(void) closedir (dir);
		}
		return state;
	  }
	   
 
	if (strcmp(stardata,"all")==0 && strcmp(program,"all")!=0 )
	  {
	   	//register <all> <program>
	    	dir = opendir (STARDATA_DIR);
		if (dir != NULL)
		{
			while ((ep = readdir (dir)))
        			if ( strcmp(ep->d_name , ".")!=0 && strcmp(ep->d_name ,"..")!=0 )
				  state = execute(program, action, ep->d_name);

      			(void) closedir (dir);
	    	}
		return state;
	  }
}
	
	

int main(int argc, char **argv)
{
	struct arguments arguments;
	int ret;

  	arguments.silent = 0;

	argp_parse (&argp, argc, argv, 0, 0, &arguments);
		
	if ((ret=process ( arguments.args[0],arguments.args[1], arguments.args[2]))==0)
			exit (EXIT_SUCCESS);
	else 
	  switch (ret)
	    {

	    case 1: 
	      if (arguments.silent!=1)
		printf("ERROR: processing.\n");
	      exit(EXIT_FAILURE);
	      break;

	    case 2:
	      if (arguments.silent!=1)
		printf("ERROR: unknown action. \n");
	      exit(EXIT_FAILURE);
	      break;

	    case 3:
	      if (arguments.silent!=1)
		printf("ERROR: program %s not found\n",arguments.args[2]);
	      exit(EXIT_FAILURE);
	      break;
	      
	    default:
	      exit (EXIT_SUCCESS);
	      
	    }

}
