#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 %s.h",
				arg->expr->Identifier,
				arg->expr->Identifier);
			}
		}
	}

	/*
	 * 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;

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

			if(asn1c_copy_over(arg, buf) == -1) {
				fprintf(mkf, ">>>ABORTED<<<");
				fclose(mkf);
				return -1;
			} else {
				fprintf(mkf, "\t\\\n\t%s", fname);
			}
		}
	}

	fprintf(mkf, "\n\n");
	fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
	fprintf(mkf, "libsomething_la_SOURCES=$(ASN_MODULE_SOURCES)\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\" found 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\" found 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 <constr_TYPE.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 <%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;
}

