#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"

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 = 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, "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 handl 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 = 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)
		return NULL;
	ff->ff_features = 0;
	ff->ff_lineno = -1;

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