/*
 * GkDebconf -- Help to configure packages with debconf
 * Copyleft (C) 2003 Agney Lopes Roth Ferraz <agney@users.sourceforge.net>
 *
 * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <dirent.h>
#include <errno.h>

#include <gtk/gtk.h>

#include "../config.h"

#include "defines.h"
#include "debconf.h"
#include "interface.h"
#include "files.h"

#define INFODIR "/var/lib/dpkg/info"
#define CONFIGEXT ".config"

extern gint errno;
extern GtkWidget *main_window;



/**
 * sort_configs:
 *
 * @a: gconstpointer that contains string a.
 * @b: gconstpointer that contains string b.
 *
 *  Compares strings.
 * Returns 0 if string a match string b. A number lass than zero if a is less than b, otherwise if a is greater than b.
 */

int
sort_configs (gconstpointer a, gconstpointer b)
{
  gchar *as = (gchar*)a;
  gchar *bs = (gchar*)b;
  return strcmp(as,bs);
}


/**
 * get_options:
 * This lists the *.config files in /var/lib/dpkg/info  and list them in Glist as packages wich
 * can be configured 
 *
 * Returns a Glist with packages that can be configured.
 */

GList *get_options ()
{
  DIR *dir;
  struct dirent *dent;
  gchar *point;
  gint i;
  GList *cflist = NULL;

  if ((dir = opendir (INFODIR)) == NULL)
    {
      perror(_("Opening "INFODIR));
      return NULL;
    }

  for (i = 3 ; (dent = readdir (dir)) ; i++)
    {
      if ((point = strrchr (dent->d_name, '.')) == NULL)
	continue;
      
      if (!strcmp (point, CONFIGEXT))
	{
	  bzero (point, strlen(point));
	  cflist = g_list_insert_sorted (cflist,
					 g_strdup (dent->d_name),
					 sort_configs);
	}
    }
  
  closedir(dir);
  
  return cflist;
}

/**
 * pkg_info:
 *
 * @all_pkgs: Glist that contains packages names.
 *  Gets all sections of installed packages
 *
 * Returns package section and description on packages on all_pkgs.
 */

GList **pkg_info(GList *all_pkgs)
{
  GList *pkg_info[2];
  GList *pkg_descriptions = NULL;
  GList *pkg_sections = NULL;
  GList *all_pkgs_copy;

  FILE *fd;
  
  gchar *p = NULL;
  gchar str[100], s[20];
  GString *desc, *cmd;

  all_pkgs_copy = all_pkgs;


  cmd = g_string_new("/usr/bin/dpkg -s");

  while (all_pkgs_copy) {
    p = all_pkgs_copy->data;
    all_pkgs_copy = all_pkgs_copy->next;

     g_string_append(cmd, " ");
     g_string_append(cmd, p);
  }

  if ((fd = popen(cmd->str, "r")) == NULL) {
    fprintf(stderr, "Can't open pipe for dpkg\n");
    return NULL;
  }

  while (! feof(fd)) {
    fgets(str, 100, fd);
    if (strstr(str, "Section: ")) {
      strcpy(s, str + 9);
      if (s[strlen(s)-1] == '\n')
	s[strlen(s)-1] = '\0';

      p = strdup(s);

      pkg_sections = g_list_append(pkg_sections, p);
    }

    
    if (strstr(str, "Description: ")) {
      desc = g_string_new( str + 12);
      fgets(str, 100, fd);
      
      do {
	if (*str) {
		int str_len = strlen(str);
	      	if (!strcmp(str+(str_len-3)," .\n"))
		     	str[str_len-2] = ' ';
	        g_string_append(desc, str);
	}
      	fgets(str, 100, fd);
      } while (!feof(fd) && !strstr(str,"Package: ") );

      p = desc->str;

      pkg_descriptions = g_list_append(pkg_descriptions, p);
      g_string_free(desc,0);	/* free wrapper but keep string */
    }
  }

  fclose(fd);

  g_string_free(cmd,1);

  pkg_info[0] = pkg_sections;
  pkg_info[1] = pkg_descriptions;

  return pkg_info;
}

/**
 * pkg_sections:
 *
 * @pkg_sections: Glist that contains packages sections.
 *
 * Extracts sections for the list from all package sections
 * Returns a Glist of sections.
 */

GList *sections(GList *pkg_sections)
{
  GList *sections = NULL;
  GList *pkg_sections_copy;
  gchar *data;

  pkg_sections_copy = g_list_copy(pkg_sections);

  while (pkg_sections_copy) {
    data = pkg_sections_copy->data;

    pkg_sections_copy = pkg_sections_copy->next;
  
    if (strlen(data) != 0) {
     
		if (g_list_find_custom(sections, data, sort_configs) == NULL) {
        	  sections = g_list_insert_sorted(sections, data, sort_configs);
		}
    }
 
  }
/* Add virtual section. labeled "*" for displaying all packages */
  sections = g_list_insert_sorted(sections, "*", sort_configs);

  return sections;
}
