/*
 *                            COPYRIGHT
 *
 *  sch-rnd - modular/flexible schematics editor - easyeda file format support
 *  Copyright (C) 2024 Tibor 'Igor2' Palinkas
 *
 *  (Supported by NLnet NGI0 Entrust Fund in 2024)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA.
 *
 *  Contact:
 *    Project page: http://repo.hu/projects/sch-rnd
 *    contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html
 *    mailing list: http://www.repo.hu/projects/sch-rnd/contact.html
 */

/* high level for the 'std' format - included from read.c; I/O entry points */

/* IO API function (load symbol from lib) */
csch_cgrp_t *io_easypro_load_grp(FILE *f, const char *fn, const char *fmt, const char *subsymname, csch_sheet_t *sheet)
{
	return io_easypro_load_grp_into(f, fn, sheet, NULL, 1);
}

/* True when the user configured zip commands */
#define CAN_UNZIP ((io_easyeda_conf.plugins.io_easyeda.zip_list_cmd != NULL) && (*io_easyeda_conf.plugins.io_easyeda.zip_list_cmd != '\0'))

/* Accept zip files that are symbols for both symbol and sheet load or
   sheets for sheet load */
int io_easypro_test_parse(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type)
{
	if (easypro_test_parse_sym(f, fn, fmt, type) == 0)
		return 0;

	if (CAN_UNZIP) {
		int is_sym, res;
		rewind(f);
		res = easypro_test_parse_zip(f, fn, fmt, type, &is_sym);
		if (res == 0) {
			if (is_sym) /* can load sym in both cases */
				return 0;
			if (type == CSCH_IOTYP_SHEET) /* can load a sheet only as a sheet */
				return 0;
		}
	}

	return -1;
}

/* load first/next file from the zip */
int io_easypro_load_sheet_bundled(void *cookie, FILE *f, const char *fn, csch_sheet_t *dst)
{
	easypro_bundle_t *bnd = cookie;
	if (bnd->is_sym)
		return easypro_load_zip_sym(bnd, dst);
	return easypro_load_zip_sheet(bnd, dst);
}

/* Bundled is called only for sheets; symbols are not bundled and are
   loaded through io_easypro_load_grp() by plug_io. If the file is accepted
   it is also unpacked into a temp dir left there for sheet loader to read
   it file by file */
void *io_easypro_test_parse_bundled(FILE *f, const char *fn, const char *fmt, csch_plug_io_type_t type)
{
	int is_sym, res;
	easypro_bundle_t *bnd;
	char *cmd, *fullpath;
	const char *prefix[4];

	if (!CAN_UNZIP)
		return NULL;

	res = easypro_test_parse_zip(f, fn, fmt, type, &is_sym);
	if (res != 0)
		return NULL;

	bnd = calloc(sizeof(easypro_bundle_t), 1);
	bnd->fn = fn;
	bnd->is_sym = is_sym;

	/* unpack: create a temp dir... */
	if (!io_easyeda_conf.plugins.io_easyeda.debug.unzip_static) {
		if (rnd_mktempdir(NULL, &bnd->tempdir, "easypro") != 0) {
			free(bnd);
			return NULL;
		}
		bnd->dir = bnd->tempdir.array;
	}
	else {
		bnd->dir = "/tmp/easypro";
		rnd_mkdir(NULL, bnd->dir, 0755);
	}

	/* ... cd to it and unpacl there with full path to the zip */
	prefix[0] = "cd ";
	prefix[1] = bnd->dir;
	prefix[2] = ";";
	prefix[3] = NULL;

	fullpath = rnd_lrealpath(fn);
	cmd = easypro_zip_cmd(prefix, io_easyeda_conf.plugins.io_easyeda.zip_extract_cmd, fullpath);
	free(fullpath);

	res = rnd_system(NULL, cmd);
	if (res != 0) {
		rnd_message(RND_MSG_ERROR, "io_easyeda: unable to unzip using command: '%s'\nDetails on stderr.\nPlease check your configuration!\n", cmd);
		free(cmd);
		io_easypro_end_bundled(bnd, fn);
		return NULL;
	}
	free(cmd);

	htss_init(&bnd->devmap, strhash, strkeyeq);
	return bnd;
}


void io_easypro_end_bundled(void *cookie, const char *fn)
{
	long n;
	easypro_bundle_t *bnd = cookie;
	htss_entry_t *e;

	if (bnd->dr != NULL)
		rnd_closedir(bnd->dr);

	/* clean up the zip */
	if (!io_easyeda_conf.plugins.io_easyeda.debug.unzip_static)
		rnd_rmtempdir(NULL, &bnd->tempdir);

	/* free temporaries */
	for(n = 0; n < bnd->sheets.used; n++)
		free(bnd->sheets.array[n]);
	vts0_uninit(&bnd->sheets);

	for(n = 0; n < bnd->syms.used; n++)
		free(bnd->syms.array[n]);
	vts0_uninit(&bnd->syms);

	if (bnd->symsheet_inited)
		csch_sheet_uninit(&bnd->symsheet);

	for(e = htss_first(&bnd->devmap); e != NULL; e = htss_next(&bnd->devmap, e)) {
		free(e->key);
		free(e->value);
	}
	htss_uninit(&bnd->devmap);

	if (bnd->symtab_inited) {
		htsp_entry_t *e;
		for(e = htsp_first(&bnd->symtab); e != NULL; e = htsp_next(&bnd->symtab, e))
			free(e->key);
		htsp_uninit(&bnd->symtab);
	}

	free(bnd);
}

