#include "Python.h"
#include "Python-ast.h"
#include "node.h"
#include "token.h"
#include "graminit.h"
#include "code.h"
#include "compile.h"
#include "symtable.h"

#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
#define ERR_LATE_FUTURE \
"from __future__ imports must occur at the beginning of the file"

static int
future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
{
	int i;
	asdl_seq *names;

	assert(s->kind == ImportFrom_kind);

	names = s->v.ImportFrom.names;
	for (i = 0; i < asdl_seq_LEN(names); i++) {
                alias_ty name = (alias_ty)asdl_seq_GET(names, i);
		const char *feature = PyString_AsString(name->name);
		if (!feature)
			return 0;
		if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
			continue;
		} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
			continue;
		} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
			ff->ff_features |= CO_FUTURE_DIVISION;
		} else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
			ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
		} else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
			ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
		} else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
			ff->ff_features |= CO_FUTURE_PRINT_FUNCTION;
		} else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
			ff->ff_features |= CO_FUTURE_UNICODE_LITERALS;
		} else if (strcmp(feature, "braces") == 0) {
			PyErr_SetString(PyExc_SyntaxError,
					"not a chance");
			PyErr_SyntaxLocation(filename, s->lineno);
			return 0;
		} else {
			PyErr_Format(PyExc_SyntaxError,
				     UNDEFINED_FUTURE_FEATURE, feature);
			PyErr_SyntaxLocation(filename, s->lineno);
			return 0;
		}
	}
	return 1;
}

static int
future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
{
	int i, found_docstring = 0, done = 0, prev_line = 0;

	static PyObject *future;
	if (!future) {
		future = PyString_InternFromString("__future__");
		if (!future)
			return 0;
	}

	if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
		return 1;

	/* A subsequent pass will detect future imports that don't
	   appear at the beginning of the file.  There's one case,
	   however, that is easier to handle here: A series of imports
	   joined by semi-colons, where the first import is a future
	   statement but some subsequent import has the future form
	   but is preceded by a regular import.
	*/
	   

	for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
		stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);

		if (done && s->lineno > prev_line)
			return 1;
		prev_line = s->lineno;

		/* The tests below will return from this function unless it is
		   still possible to find a future statement.  The only things
		   that can precede a future statement are another future
		   statement and a doc string.
		*/

		if (s->kind == ImportFrom_kind) {
			if (s->v.ImportFrom.module == future) {
				if (done) {
					PyErr_SetString(PyExc_SyntaxError,
							ERR_LATE_FUTURE);
					PyErr_SyntaxLocation(filename, 
							     s->lineno);
					return 0;
				}
				if (!future_check_features(ff, s, filename))
					return 0;
				ff->ff_lineno = s->lineno;
			}
			else
				done = 1;
		}
		else if (s->kind == Expr_kind && !found_docstring) {
			expr_ty e = s->v.Expr.value;
			if (e->kind != Str_kind)
				done = 1;
			else
				found_docstring = 1;
		}
		else
			done = 1;
	}
	return 1;
}


PyFutureFeatures *
PyFuture_FromAST(mod_ty mod, const char *filename)
{
	PyFutureFeatures *ff;

	ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
	if (ff == NULL) {
		PyErr_NoMemory();
		return NULL;
	}
	ff->ff_features = 0;
	ff->ff_lineno = -1;

	if (!future_parse(ff, mod, filename)) {
		PyObject_Free(ff);
		return NULL;
	}
	return ff;
}
