#include "asn1c_internal.h"
#include <asn1fix_export.h>

#ifndef	DEFFILEMODE	/* Normally in <sys/stat.h> */
#define	DEFFILEMODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#endif

/*
 * Construct identifier from multiple parts.
 * Convert unsafe characters to underscores.
 */
char *
asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...) {
	static char *storage;
	static int storage_size;
	int nodelimiter = 0;
	va_list ap;
	char *str;
	int size;
	char *p;

	if(arg1 == NULL)
		return NULL;

	/*
	 * Estimate the necessary storage size
	 */
	size = strlen(arg1);
	va_start(ap, arg1);
	while((str = va_arg(ap, char *)))
		size += 1 + strlen(str);
	va_end(ap);

	/*
	 * Make sure we have this amount of storage.
	 */
	if(storage_size <= size) {
		if(storage) free(storage);
		storage = malloc(size + 1);
		if(storage) {
			storage_size = size;
		} else {
			storage_size = 0;
			return NULL;
		}
	}

	/*
	 * Fill-in the storage.
	 */
	va_start(ap, arg1);
	str = arg1;
	p = storage;
	for(str = arg1; str; str = va_arg(ap, char *)) {
		int subst_made = 0;

		if(str[0] == ' ' && str[1] == '\0') {
			*p++ = ' ';
			nodelimiter = 1;	/* No delimiter */
			continue;
		}

		if(str != arg1 && !nodelimiter)
			*p++ = '_';	/* Delimiter between tokens */
		nodelimiter = 0;

		for(; *str; str++) {
			if(isalnum(*str)) {
				*p++ = *str;
				subst_made = 0;
			} else if(!subst_made++) {
				if(unsafe_only_spaces && !isspace(*str)) {
					*p ++ = *str;
				} else {
					*p++ = '_';
				}
			}
		}
	}
	va_end(ap);
	*p = '\0';

	assert((p - storage) <= storage_size);

	return storage;
}

FILE *
asn1c_open_file(arg_t *arg, const char *name, const char *ext) {
	int created = 1;
	struct stat sb;
	char *fname;
	int len;
	FILE *fp;
	int fd;

	(void)arg;	/* Unused argument */

	/*
	 * Compute filenames.
	 */
	len = strlen(name) + strlen(ext) + 1;
	fname = alloca(len);
	snprintf(fname, len, "%s%s", name, ext);

	/*
	 * Create files.
	 */
	fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
	if(fd == -1 && errno == EEXIST) {
		fd = open(fname, O_WRONLY, DEFFILEMODE);
		created = 0;
	}
	if(fd == -1) {
		perror(fname);
		return NULL;
	}

	/*
	 * Check sanity.
	 */
	if(fstat(fd, &sb) || !S_ISREG(sb.st_mode)) {
		fprintf(stderr, "%s: Not a regular file\n", fname);
		if(created) unlink(fname);
		close(fd);
		return NULL;
	}

	(void)ftruncate(fd, 0);

	/*
	 * Convert file descriptor into file pointer.
	 */
	fp = fdopen(fd, "w");
	if(fp == NULL) {
		if(created) unlink(fname);
		close(fd);
	}
	return fp;
}

char *
asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
	char *typename;

	switch(expr->expr_type) {
	case A1TC_REFERENCE:
		typename = expr->reference->components[
			expr->reference->comp_count-1].name;
		if(typename[0] == '&') {
			arg_t tmp = *arg;

			/*
			 * This is a reference to a type defined in a class.
			 * Resolve it and use instead.
			 */
			tmp.expr = asn1f_class_access_ex(arg->asn, arg->mod,
				arg->expr, expr->reference, &tmp.mod);
			if(tmp.expr) return NULL;

			return asn1c_type_name(&tmp, tmp.expr, _format);
		} else if(_format == TNF_RSAFE) {
			/*
			 * The recursion-safe format is requested.
			 * The problem here is that only constructed types
			 * might be referenced with "struct".
			 * Change RSAFE to CTYPE if the terminal type
			 * is primitive.
			 */
			asn1p_expr_t *terminal;
			terminal = asn1f_find_terminal_type_ex(
				arg->asn, arg->mod, arg->expr, NULL);
			if(terminal
			&& (terminal->expr_type
				& (ASN_BASIC_MASK | ASN_STRING_MASK)))
				_format = TNF_CTYPE;
		}
		break;
	case ASN_CONSTR_SEQUENCE_OF:
	case ASN_CONSTR_SET_OF:
		if(expr->Identifier) {
			typename = expr->Identifier;
		} else {
			asn1p_expr_t *child;
			child = TQ_FIRST(&(expr->members));
			typename = asn1c_type_name(arg, child, _format);
			if(typename)
				return typename;
			_format = TNF_SAFE;
			typename = child->Identifier;
		}
		break;
	case ASN_BASIC_INTEGER:
	case ASN_BASIC_ENUMERATED:
		if((arg->flags & A1C_USE_NATIVE_INTEGERS)) {
			switch(_format) {
			case TNF_CTYPE:
			case TNF_RSAFE:
				return "int";
			default:
				if(expr->expr_type == ASN_BASIC_INTEGER)
					return "NativeInteger";
				else
					return "NativeEnumerated";
			}
		}
		/* Fall through */
	default:
		if(expr->expr_type & (ASN_BASIC_MASK | ASN_STRING_MASK)) {
			if(_format == TNF_RSAFE)
				_format = TNF_CTYPE;
			typename = ASN_EXPR_TYPE2STR(expr->expr_type);
		} else {
			_format = TNF_SAFE;
			typename = expr->Identifier;
		}
	}

	switch(_format) {
	case TNF_UNMODIFIED:
	case TNF_INCLUDE:
		return asn1c_make_identifier(1, typename, 0);
	case TNF_SAFE:
		return asn1c_make_identifier(0, typename, 0);
	case TNF_CTYPE:
		return asn1c_make_identifier(0, typename, "t", 0);
	case TNF_RSAFE:
		return asn1c_make_identifier(0, "struct", " ", typename, 0);
	}

	assert("!unreachable");
	return typename;
}

