#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "sysfs.h"
#include "si.h"

static char * top_dir = ".";


struct si_ls_data {
	char	** d_start;
	int	d_num;
	struct record_col	d_obj_col;
	struct record_col	d_attr_col;
	struct record_col	d_link_col;
};

static int parse_args(struct si_action * a, struct si_ls_data * d)
{
	if (a->a_argc) {
		d->d_start = a->a_argv;
		d->d_num = a->a_argc;
	} else {
		d->d_start = &top_dir;
		d->d_num = 1;
	}
	return 0;
}

static int ls_init(struct si_action * a)
{
	struct si_ls_data * d;
	int error;

	d = malloc(sizeof(struct si_ls_data));
	if (!d)
		return -ENOMEM;
	memset(d, 0, sizeof(struct si_ls_data));

	error = parse_args(a, d);

	if (!error)
		a->a_data = d;
	else
		free(d);
	return error;
}


static int record_object(struct si_action * a, struct sysfs_object * so)
{
	struct si_ls_data * data = a->a_data;
	int error;

	if (a->a_show_objs) {
		error = record_children(a, &data->d_obj_col);
		if (!error) {
			data->d_obj_col.rc_name = "Child";
			data->d_obj_col.rc_suf = "ren";
		} else
			goto Done;
	}

	if (a->a_show_attrs) {
		error = record_attributes(a, &data->d_attr_col);
		if (!error) {
			data->d_attr_col.rc_name = "Attribute";
			data->d_attr_col.rc_suf = "s";
		} else
			goto Done;
	}

	if (a->a_show_links) {
		error = record_links(a, &data->d_link_col);
		if (!error) {
			data->d_link_col.rc_name = "Link";
			data->d_link_col.rc_suf = "s";
		} else
			goto Done;
	}
 Done:
	return error;
}

static int ls_exec(struct si_action * a)
{
	struct si_ls_data * data = a->a_data;
	struct sysfs_object so;
	int error = 0;
	int i;

	for (i = 0; i < data->d_num; i++) {
		error = sysfs_object_init(&so, data->d_start[i]);
		if (error)
			break;
		record_object(a, &so);
		sysfs_object_exit(&so);
	}
	return error;
}

static void ls_exit(struct si_action * a)
{
	struct si_ls_data * d = a->a_data;

	a->a_data = NULL;

	rc_exit(&d->d_obj_col);
	rc_exit(&d->d_attr_col);
	rc_exit(&d->d_link_col);

	if (d)
		free(d);
}

static const char * ls_help = "Print Object Information";
static const char * ls_usage = "<object> ...";

decl_cmd(ls);
