#include "asn1c_internal.h"
#include "asn1c_compat.h"
#include "asn1c_fdeps.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->targets[i]) == NULL)
			continue;

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

		TQ_FOR(ot, &(cs->targets[i]), 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->targets[OT_INCLUDES]), next) {
		asn1c_activate_dependency(deps, 0, ot->buf);
		fwrite(ot->buf, ot->len, 1, fp_h);
	}
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
		fwrite(ot->buf, ot->len, 1, fp_h);
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
		fwrite(ot->buf, ot->len, 1, fp_h);
	fprintf(fp_h, "\n");
	TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), 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->targets[OT_STAT_DEFS]), next)
		fwrite(ot->buf, ot->len, 1, fp_c);
	TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
		fwrite(ot->buf, ot->len, 1, fp_c);

	assert(OT_MAX == 7);

	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;
}

