#include <ctype.h>
#include <string.h>

#include "buffer.h"
#include "log.h"
#include "mod_ssi.h"
#include "mod_ssi_expr.h"
#include "mod_ssi_exprparser.h"

typedef struct {
	const char *input;
	size_t offset;
	size_t size;

	int line_pos;

	int in_key;
	int in_brace;
	int in_cond;
} ssi_tokenizer_t;

ssi_val_t *ssi_val_init() {
	ssi_val_t *s;

	s = calloc(1, sizeof(*s));

	return s;
}

void ssi_val_free(ssi_val_t *s) {
	if (s->str) buffer_free(s->str);

	free(s);
}

int ssi_val_tobool(ssi_val_t *B) {
	if (B->type == SSI_TYPE_STRING) {
		return B->str->used > 1 ? 1 : 0;
	} else {
		return B->bo;
	}
}

static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
			      ssi_tokenizer_t *t, int *token_id, buffer *token) {
	int tid = 0;
	size_t i;

	UNUSED(con);

	for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
		char c = t->input[t->offset];
		data_string *ds;

		switch (c) {
		case '=':
			tid = TK_EQ;

			t->offset++;
			t->line_pos++;

			buffer_copy_string(token, "(=)");

			break;
		case '>':
			if (t->input[t->offset + 1] == '=') {
				t->offset += 2;
				t->line_pos += 2;

				tid = TK_GE;

				buffer_copy_string(token, "(>=)");
			} else {
				t->offset += 1;
				t->line_pos += 1;

				tid = TK_GT;

				buffer_copy_string(token, "(>)");
			}

			break;
		case '<':
			if (t->input[t->offset + 1] == '=') {
				t->offset += 2;
				t->line_pos += 2;

				tid = TK_LE;

				buffer_copy_string(token, "(<=)");
			} else {
				t->offset += 1;
				t->line_pos += 1;

				tid = TK_LT;

				buffer_copy_string(token, "(<)");
			}

			break;

		case '!':
			if (t->input[t->offset + 1] == '=') {
				t->offset += 2;
				t->line_pos += 2;

				tid = TK_NE;

				buffer_copy_string(token, "(!=)");
			} else {
				t->offset += 1;
				t->line_pos += 1;

				tid = TK_NOT;

				buffer_copy_string(token, "(!)");
			}

			break;
		case '&':
			if (t->input[t->offset + 1] == '&') {
				t->offset += 2;
				t->line_pos += 2;

				tid = TK_AND;

				buffer_copy_string(token, "(&&)");
			} else {
				log_error_write(srv, __FILE__, __LINE__, "sds",
						"pos:", t->line_pos,
						"missing second &");
				return -1;
			}

			break;
		case '|':
			if (t->input[t->offset + 1] == '|') {
				t->offset += 2;
				t->line_pos += 2;

				tid = TK_OR;

				buffer_copy_string(token, "(||)");
			} else {
				log_error_write(srv, __FILE__, __LINE__, "sds",
						"pos:", t->line_pos,
						"missing second |");
				return -1;
			}

			break;
		case '\t':
		case ' ':
			t->offset++;
			t->line_pos++;
			break;

		case '\'':
			/* search for the terminating " */
			for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\'';  i++);

			if (t->input[t->offset + i]) {
				tid = TK_VALUE;

				buffer_copy_string_len(token, t->input + t->offset + 1, i-1);

				t->offset += i + 1;
				t->line_pos += i + 1;
			} else {
				/* ERROR */

				log_error_write(srv, __FILE__, __LINE__, "sds",
						"pos:", t->line_pos,
						"missing closing quote");

				return -1;
			}

			break;
		case '(':
			t->offset++;
			t->in_brace++;

			tid = TK_LPARAN;

			buffer_copy_string(token, "(");
			break;
		case ')':
			t->offset++;
			t->in_brace--;

			tid = TK_RPARAN;

			buffer_copy_string(token, ")");
			break;
		case '$':
			if (t->input[t->offset + 1] == '{') {
				for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}';  i++);

				if (t->input[t->offset + i] != '}') {
					log_error_write(srv, __FILE__, __LINE__, "sds",
							"pos:", t->line_pos,
							"missing closing quote");

					return -1;
				}

				buffer_copy_string_len(token, t->input + t->offset + 2, i-3);
			} else {
				for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_';  i++);

				buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
			}

			tid = TK_VALUE;

			if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
				buffer_copy_string_buffer(token, ds->value);
			} else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
				buffer_copy_string_buffer(token, ds->value);
			} else {
				buffer_copy_string(token, "");
			}

			t->offset += i;
			t->line_pos += i;

			break;
		default:
			for (i = 0; isgraph(t->input[t->offset + i]);  i++) {
				char d = t->input[t->offset + i];
				switch(d) {
				case ' ':
				case '\t':
				case ')':
				case '(':
				case '\'':
				case '=':
				case '!':
				case '<':
				case '>':
				case '&':
				case '|':
					break;
				}
			}

			tid = TK_VALUE;

			buffer_copy_string_len(token, t->input + t->offset, i);

			t->offset += i;
			t->line_pos += i;

			break;
		}
	}

	if (tid) {
		*token_id = tid;

		return 1;
	} else if (t->offset < t->size) {
		log_error_write(srv, __FILE__, __LINE__, "sds",
				"pos:", t->line_pos,
				"foobar");
	}
	return 0;
}

int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr) {
	ssi_tokenizer_t t;
	void *pParser;
	int token_id;
	buffer *token;
	ssi_ctx_t context;
	int ret;

	t.input = expr;
	t.offset = 0;
	t.size = strlen(expr);
	t.line_pos = 1;

	t.in_key = 1;
	t.in_brace = 0;
	t.in_cond = 0;

	context.ok = 1;
	context.srv = srv;

	/* default context */

	pParser = ssiexprparserAlloc( malloc );
	token = buffer_init();
	while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) {
		ssiexprparser(pParser, token_id, token, &context);

		token = buffer_init();
	}
	ssiexprparser(pParser, 0, token, &context);
	ssiexprparserFree(pParser, free );

	buffer_free(token);

	if (ret == -1) {
		log_error_write(srv, __FILE__, __LINE__, "s",
				"expr parser failed");
		return -1;
	}

	if (context.ok == 0) {
		log_error_write(srv, __FILE__, __LINE__, "sds",
				"pos:", t.line_pos,
				"parser failed somehow near here");
		return -1;
	}
#if 0
	log_error_write(srv, __FILE__, __LINE__, "ssd",
			"expr: ",
			expr,
			context.val.bo);
#endif
	return context.val.bo;
}
