#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "../include/cloog/cloog.h"

#define ALLOC(type) (type*)malloc(sizeof(type))

static char *next_line(FILE *input, char *line, unsigned len)
{
	char *p;

	do {
		if (!(p = fgets(line, len, input)))
			return NULL;
		while (isspace(*p) && *p != '\n')
			++p;
	} while (*p == '#' || *p == '\n');

	return p;
}

/**
 * Read input from a .cloog file, putting most of the information
 * in the returned CloogInput.  The chosen language is put in
 * options->language.
 */
CloogInput *cloog_input_read(FILE *file, CloogOptions *options)
{
	char line[MAX_STRING];
	char language;
	CloogDomain *context;
	CloogUnionDomain *ud;
	int nb_par;

	/* First of all, we read the language to use. */
	if (!next_line(file, line, sizeof(line)))
		cloog_die("Input error.\n");
	if (sscanf(line, "%c", &language) != 1)
		cloog_die("Input error.\n");
   
	if (language == 'f')
		options->language = LANGUAGE_FORTRAN;
	else
		options->language = LANGUAGE_C;

	/* We then read the context data. */
	context = cloog_domain_read_context(options->state, file);
	nb_par = cloog_domain_parameter_dimension(context);

	ud = cloog_union_domain_read(file, nb_par, options);

	return cloog_input_alloc(context, ud);
}

/**
 * Create a CloogInput from a CloogDomain context and a CloogUnionDomain.
 */
CloogInput *cloog_input_alloc(CloogDomain *context, CloogUnionDomain *ud)
{
	CloogInput *input;

	input = ALLOC(CloogInput);
	if (!input)
		cloog_die("memory overflow.\n");

	input->context = context;
	input->ud = ud;

	return input;
}

void cloog_input_free(CloogInput *input)
{
	cloog_domain_free(input->context);
	cloog_union_domain_free(input->ud);
	free(input);
}

static void print_names(FILE *file, CloogUnionDomain *ud,
	enum cloog_dim_type type, const char *name)
{
	int i;

	fprintf(file, "\n%d # %s name(s)\n", ud->name[type] ? 1 : 0, name);
	if (!ud->name[type])
		return;

	for (i = 0; i < ud->n_name[type]; i++)
		fprintf(file, "%s ", ud->name[type][i]);

	fprintf(file, "\n");
}

/**
 * Dump the .cloog description of a CloogInput and a CloogOptions data structure
 * into a file. The generated .cloog file will contain the same information as
 * the data structures. The file can be used to run the cloog program on the
 * example.
 */
void cloog_input_dump_cloog(FILE *file, CloogInput *input, CloogOptions *opt)
{
        int i, num_statements;
        CloogUnionDomain *ud = input->ud;
        CloogNamedDomainList *ndl = ud->domain;

        fprintf(file,
                "# CLooG -> CLooG\n"
                "# This is an automatic dump of a CLooG input file from a "
                "CloogInput data\n"
                "# structure.\n\n");

        /* Language. */
        if (opt->language == LANGUAGE_FORTRAN) {
                fprintf(file, "# Language: FORTRAN\n");
                fprintf(file, "f\n\n");
        } else {
                fprintf(file, "# Language: C\n");
                fprintf(file, "c\n\n");
        }

        /* Context. */
        fprintf(file, "# Context:\n");
        cloog_domain_print_constraints(file, input->context, 1);

	print_names(file, ud, CLOOG_PARAM, "Parameter");

        /* Statement number. */
        i = 0;
        while (ndl != NULL) {
        	i++;
        	ndl = ndl->next;
        }
        num_statements = i;
        fprintf(file, "\n# Statement number:\n%d\n\n", num_statements);

        /* Iteration domains. */
        i = 1;
        ndl = ud->domain;
        while (ndl != NULL) {
                fprintf(file, "# Iteration domain of statement %d (%s).\n", i,
                        ndl->name);

                cloog_domain_print_constraints(file, ndl->domain, 1);
                fprintf(file,"\n0 0 0 # For future options.\n\n");

                i++;
                ndl = ndl->next;
        }

	print_names(file, ud, CLOOG_ITER, "Iterator");

        /* Exit, if no scattering is supplied. */
        if (!ud->domain || !ud->domain->scattering) {
                fprintf(file, "# No scattering functions.\n0\n\n");
                return;
        }

        /* Scattering relations. */
        fprintf(file,
                "# --------------------- SCATTERING --------------------\n");

        fprintf(file, "%d # Scattering functions\n", num_statements);

        i = 1;
        ndl = ud->domain;
        while (ndl != NULL) {
                fprintf(file, "\n# Scattering of statement %d (%s).\n", i,
                        ndl->name);

                cloog_scattering_print_constraints(file, ndl->scattering);

                i++;
                ndl = ndl->next;
        }

	print_names(file, ud, CLOOG_SCAT, "Scattering dimension");
}
