#include "asn1c_internal.h"
#include "asn1c_compat.h"
#include "asn1c_fdeps.h"
#include "asn1c_lang.h"
#include "asn1c_misc.h"
#include "asn1c_save.h"
#include "asn1c_out.h"

static int asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *);
static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
static int asn1c_copy_over(arg_t *arg, char *path);

int
asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
	asn1c_fdeps_t *deps = 0;
	FILE *mkf;
	asn1c_fdeps_t *dlist;

	deps = asn1c_read_file_dependencies(arg, datadir);
	if(!deps && datadir) {
		WARNING("Cannot read file-dependencies information "
			"from %s\n", datadir);
	}

	TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
		TQ_FOR(arg->expr, &(arg->mod->members), next) {
			if(asn1_lang_map[arg->expr->meta_type]
				[arg->expr->expr_type].type_cb) {
				if(asn1c_dump_streams(arg, deps))
					return -1;
			}
		}
	}

	/*
	 * Dump out the Makefile template and the rest of the support code.
	 */
	if((arg->flags & A1C_PRINT_COMPILED)
	|| (arg->flags & A1C_OMIT_SUPPORT_CODE)) {
		return 0;	/* Finished */
	}

	mkf = asn1c_open_file("Makefile.am", ".sample");
	if(mkf == NULL) {
		perror("Makefile.am.sample");
		return -1;
	}

	fprintf(mkf, "ASN_MODULE_SOURCES=");
	TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
		TQ_FOR(arg->expr, &(arg->mod->members), next) {
			if(asn1_lang_map[arg->expr->meta_type]
				[arg->expr->expr_type].type_cb) {
				fprintf(mkf, "\t\\\n\t%s.c",
				arg->expr->Identifier);
			}
		}
	}
	fprintf(mkf, "\n\nASN_MODULE_HEADERS=");
	TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
		TQ_FOR(arg->expr, &(arg->mod->members), next) {
			if(asn1_lang_map[arg->expr->meta_type]
				[arg->expr->expr_type].type_cb) {
				fprintf(mkf, "\t\\\n\t%s.h",
				arg->expr->Identifier);
			}
		}
	}
	fprintf(mkf, "\n\n");

	/*
	 * Move necessary skeleton files and add them to Makefile.am.sample.
	 */
	dlist = asn1c_deps_makelist(deps);
	if(dlist) {
		char buf[8129];
		char *dir_end;
		int i = strlen(datadir);

		assert(i < (int)(sizeof(buf) / 2 - 2));
		memcpy(buf, datadir, i);
		dir_end = buf + i;
		*dir_end++ = '/';

		for(i = 0; i < dlist->el_count; i++) {
			char *fname = dlist->elements[i]->filename;
			char *dotH;

			assert(strlen(fname) < (sizeof(buf) / 2));
			strcpy(dir_end, fname);

			if(asn1c_copy_over(arg, buf) == -1) {
				fprintf(mkf, ">>>ABORTED<<<");
				fclose(mkf);
				return -1;
			}
			dotH = strrchr(fname, 'h');
			if(dotH && fname<dotH && dotH[-1] == '.' && !dotH[1]) {
				fprintf(mkf, "ASN_MODULE_HEADERS+=%s\n", fname);
			} else {
				fprintf(mkf, "ASN_MODULE_SOURCES+=%s\n", fname);
			}
		}
	}

	fprintf(mkf, "\n\n"
		"lib_LTLIBRARIES=libsomething.la\n"
		"libsomething_la_SOURCES="
			"$(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)\n"
		"\n"
		"# This file may be used as an input for make(3)\n"
		"# Remove the lines below to convert it into a pure .am file\n"
		"TARGET = progname\n"
		"CFLAGS += -I.\n"
		"OBJS=${ASN_MODULE_SOURCES:.c=.o} $(TARGET).o\n"
		"\nall: $(TARGET)\n"
		"\n$(TARGET): ${OBJS}"
		"\n\t$(CC) $(CFLAGS) -o $(TARGET) ${OBJS} $(LDFLAGS) $(LIBS)\n"
		"\n.SUFFIXES:"
		"\n.SUFFIXES: .c .o\n"
		"\n.c.o:"
		"\n\t$(CC) $(CFLAGS) -o $@ -c $<\n"
		"\nclean:"
		"\n\trm -f $(TARGET)"
		"\n\trm -f $(OBJS)\n"
		"\n"
	);
	fclose(mkf);
	fprintf(stderr, "Generated Makefile.am.sample\n");

	return 0;
}

/*
 * Dump the streams.
 */
static int
asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *deps)  {
	if(arg->flags & A1C_PRINT_COMPILED) {
		return asn1c_print_streams(arg);
	} else {
		return asn1c_save_streams(arg, deps);
	}
}

static int
asn1c_print_streams(arg_t *arg)  {
	compiler_streams_t *cs = arg->expr->data;
	asn1p_expr_t *expr = arg->expr;
	int i;

	for(i = 1; i < OT_MAX; i++) {
		out_chunk_t *ot;
		if(TQ_FIRST(&cs->destination[i].chunks) == NULL)
			continue;

		printf("\n/*** <<< %s [%s] >>> ***/\n\n",
			_compiler_stream2str[i],
			expr->Identifier);

		TQ_FOR(ot, &(cs->destination[i].chunks), next) {
			fwrite(ot->buf, ot->len, 1, stdout);
		}
	}

	return 0;
}

static int
asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
	asn1p_expr_t *expr = arg->expr;
	compiler_streams_t *cs = expr->data;
	out_chunk_t *ot;
	FILE *fp_c, *fp_h;
	char *header_id;

	if(cs == NULL) {
		fprintf(stderr, "Cannot compile %s at line %d\n",
			expr->Identifier, expr->_lineno);
		return -1;
	}

	fp_c = asn1c_open_file(expr->Identifier, ".c");
	fp_h = asn1c_open_file(expr->Identifier, ".h");
	if(fp_c == NULL || fp_h == NULL) {
		if(fp_c) fclose(fp_c);	/* lacks unlink() */
		if(fp_h) fclose(fp_h);	/* lacks unlink() */
		return -1;
	}

	fprintf(fp_c,
	"/*\n"
	" * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
	" * From ASN.1 module \"%s\"\n"
	" * \tfound in \"%s\"\n"
	" */\n\n",
		arg->mod->Identifier,
		arg->mod->source_file_name
	);
	fprintf(fp_h,
	"/*\n"
	" * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
	" * From ASN.1 module \"%s\"\n"
	" * \tfound in \"%s\"\n"
	" */\n\n",
		arg->mod->Identifier,
		arg->mod->source_file_name
	);

	header_id = asn1c_make_identifier(0, expr->Identifier, NULL);
	fprintf(fp_h,
		"#ifndef\t_%s_H_\n"
		"#define\t_%s_H_\n"
		"\n", header_id, header_id);

	fprintf(fp_h, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");

	fprintf(fp_h, "#include <asn_application.h>\n\n");

	TQ_FOR(ot, &(cs->destination[OT_INCLUDES].chunks), next) {
		asn1c_activate_dependency(deps, 0, ot->buf);
		fwrite(ot->buf, ot->len, 1, fp_h);
	}
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->destination[OT_DEPS].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_h);
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->destination[OT_TYPE_DECLS].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_h);
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->destination[OT_FUNC_DECLS].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_h);

	fprintf(fp_h, "\n#ifdef __cplusplus\n}\n#endif\n\n"
			"#endif\t/* _%s_H_ */\n",
		header_id);

	fprintf(fp_c, "#include <asn_internal.h>\n\n");
	fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier);	/* Myself */
	TQ_FOR(ot, &(cs->destination[OT_CTABLES].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_c);
	TQ_FOR(ot, &(cs->destination[OT_CODE].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_c);
	TQ_FOR(ot, &(cs->destination[OT_STAT_DEFS].chunks), next)
		fwrite(ot->buf, ot->len, 1, fp_c);

	assert(OT_MAX == 8);

	fclose(fp_c);
	fclose(fp_h);
	fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
	fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
	return 0;
}

static int
asn1c_copy_over(arg_t *arg, char *path) {
	char *fname;

	(void)arg;	/* Unused argument */

	fname = a1c_basename(path);
	if(!fname || symlink(path, fname)) {
		if(errno == EEXIST) {
			struct stat sb1, sb2;
			if(stat(path, &sb1) == 0
			&& stat(fname, &sb2) == 0
			&& sb1.st_dev == sb2.st_dev
			&& sb1.st_ino == sb2.st_ino) {
				/*
				 * Nothing to do.
				 */
				fprintf(stderr,
					"File %s is already here as %s\n",
					path, fname);
				return 1;
			} else {
				fprintf(stderr,
					"Retaining local %s (%s suggested)\n",
					fname, path);
				return 1;
			}
		} else if(errno == ENOENT) {
			/* Ignore this */
			return 0;
		} else {
			fprintf(stderr, "Symlink %s -> %s failed: %s\n",
				path, fname, strerror(errno));
			return -1;
		}
	}

	fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);

	return 1;
}

