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

#include "asn1parser.h"
#include "asn1p_class.h"

asn1p_ioc_table_t *
asn1p_ioc_table_new() {
    asn1p_ioc_table_t *it = calloc(1, sizeof(*it));
    assert(it);
    return it;
}

void
asn1p_ioc_table_add(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
    assert(it);

    asn1p_ioc_row_t **new_rows =
        realloc(it->row, (it->rows + 1) * sizeof(it->row[0]));
    assert(new_rows);
    it->row = new_rows;
    it->row[it->rows++] = row;
}

void
asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src) {

    if(!src) return;

    for(size_t i = 0; i < src->rows; i++) {
        asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i]));
    }
}

void
asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
    if(it) {
        for(size_t i = 0; i < it->rows; i++) {
            asn1p_ioc_row_delete(it->row[i]);
        }
        free(it->row);
        free(it);
    }
}

size_t
asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) {
    size_t max_length = 0;
    if(it) {
        for(size_t i = 0; i < it->rows; i++) {
            size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]);
            if(len > max_length) max_length = len;
        }
    }
    return max_length;
}

size_t
asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) {
    size_t max_length = 0;
    if(row) {
        for(size_t i = 0; i < row->columns; i++) {
            if(row->column[i].value) {
                size_t len = strlen(row->column[i].value->Identifier);
                if(len > max_length) max_length = len;
            }
        }
    }
    return max_length;
}

asn1p_ioc_row_t *
asn1p_ioc_row_new(asn1p_expr_t *oclass) {
	asn1p_ioc_row_t *row;
	asn1p_expr_t *field;
	int columns = 0;

	assert(oclass->expr_type == A1TC_CLASSDEF);

	row = calloc(1, sizeof *row);
	if(!row) return NULL;

	TQ_FOR(field, &oclass->members, next)
		columns++;

	row->column = calloc(columns, sizeof *row->column);
	if(!row->column) {
		free(row);
		return NULL;
	}
	row->columns = columns;

	columns = 0;
	TQ_FOR(field, &oclass->members, next) {
		row->column[columns].field = field;
		row->column[columns].value = NULL;
		columns++;
	}

	return row;
}

asn1p_ioc_row_t *
asn1p_ioc_row_clone(asn1p_ioc_row_t *src) {
	asn1p_ioc_row_t *row;

	row = calloc(1, sizeof *row);
	if(!row) return NULL;

	row->column = calloc(src->columns, sizeof *src->column);
	if(!row->column) {
		free(row);
		return NULL;
	}
	row->columns = src->columns;

	for(size_t i = 0; i < src->columns; i++) {
		row->column[i].field = src->column[i].field;
		row->column[i].value = src->column[i].value ? asn1p_expr_clone(src->column[i].value, 0) : 0;
		row->column[i].new_ref = 1;
	}

	return row;
}

void
asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
	if(row) {
		if(row->column) {
			for(size_t i = 0; i < row->columns; i++) {
				if(!row->column[i].new_ref && row->column[i].value) {
					/* 
					 * Field 'reference' comes from asn1fix_cws.c :
					 * TQ_FIRST(&cell->field->members)->reference
					 * so it should not be freed here.
					 */
					row->column[i].value->reference = NULL;
				}
				asn1p_expr_free(row->column[i].value);
			}
			free(row->column);
		}
		free(row);
	}
}

int
asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) {
    assert(a && b);

    if(a->columns != b->columns)
        return -1;  /* Bad! */

    for(size_t i = 0; i < a->columns; i++) {
        assert(a->column[i].field);
        assert(b->column[i].field);
        if(strcmp(a->column[i].field->Identifier,
                  b->column[i].field->Identifier)
           != 0) {
            return -1;  /* Bad! */
        }
        if((a->column[i].value && !b->column[i].value)
           || (!a->column[i].value && b->column[i].value)) {
            return 1;   /* Not match */
        }
        if(a->column[i].value && b->column[i].value) {
            if(asn1p_expr_compare(a->column[i].value, b->column[i].value)
               != 0) {
                return 1;   /* Not match */
            }
        }
    }

    return 0;
}

struct asn1p_ioc_cell_s *
asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
	for(size_t i = 0; i < row->columns; i++) {
		if(strcmp(row->column[i].field->Identifier, fieldname) == 0)
			return &row->column[i];
	}
	errno = ESRCH;
	return NULL;
}

asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_new() {
	asn1p_wsyntx_chunk_t *wc;

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

	return wc;
}

void
asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) {
	if(wc) {
		switch(wc->type) {
		case WC_LITERAL:
		case WC_WHITESPACE:
		case WC_FIELD:
			free(wc->content.token); break;
		case WC_OPTIONALGROUP:
			asn1p_wsyntx_free(wc->content.syntax);
			break;
		}
		free(wc);
	}
}

asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) {
	asn1p_wsyntx_chunk_t *nc;

	nc = asn1p_wsyntx_chunk_new();
	if(nc) {
		nc->type = wc->type;
		switch(wc->type) {
		case WC_LITERAL:
		case WC_WHITESPACE:
		case WC_FIELD:
			nc->content.token = malloc(strlen(wc->content.token)+1);
			strcpy(nc->content.token, wc->content.token);
			break;
		case WC_OPTIONALGROUP:
			nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax);
			break;
		}
	}

	return nc;
}

asn1p_wsyntx_t *
asn1p_wsyntx_new() {
	asn1p_wsyntx_t *wx;

	wx = calloc(1, sizeof(*wx));
	if(wx) {
		TQ_INIT(&(wx->chunks));
	}

	return wx;
}

void
asn1p_wsyntx_free(asn1p_wsyntx_t *wx) {
	if(wx) {
		asn1p_wsyntx_chunk_t *wc;
		while((wc = TQ_REMOVE(&(wx->chunks), next)))
			asn1p_wsyntx_chunk_free(wc);
		free(wx);
	}
}

asn1p_wsyntx_t *
asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
	asn1p_wsyntx_t *nw;

	nw = asn1p_wsyntx_new();
	if(nw) {
		asn1p_wsyntx_chunk_t *wc;
		asn1p_wsyntx_chunk_t *nc;
		TQ_FOR(wc, &(wx->chunks), next) {
			nc = asn1p_wsyntx_chunk_clone(wc);
			if(nc) {
				TQ_ADD(&(nw->chunks), nc, next);
			} else {
				asn1p_wsyntx_free(nw);
				return NULL;
			}
		}
	}

	return nw;
}

asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) {
	asn1p_wsyntx_chunk_t *wc;

	if(do_copy) {
		static asn1p_wsyntx_chunk_t tmp;
		tmp.type = WC_LITERAL;
		tmp.content.token = token;
		wc = asn1p_wsyntx_chunk_clone(&tmp);
	} else {
		wc = asn1p_wsyntx_chunk_new();
		if(wc) {
			wc->type = WC_LITERAL;
			wc->content.token = token;
		}
	}

	return wc;
}


asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) {
	asn1p_wsyntx_chunk_t *wc;

	wc = asn1p_wsyntx_chunk_new();
	if(wc) {
		wc->type = WC_OPTIONALGROUP;
		wc->content.syntax = syntax;
		syntax->parent = wc;
	}

	return wc;
}

