/*
 *                            COPYRIGHT
 *
 *  cschem - modular/flexible schematics editor - sch-rnd (executable)
 *  Copyright (C) 2023 Tibor 'Igor2' Palinkas
 *
 *  (Supported by NLnet NGI0 Entrust in 2023)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.*
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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
 */

#include "config.h"

#include <librnd/core/compat_lrealpath.h>
#include <librnd/core/compat_fs.h>
#include <librnd/core/misc_util.h>

#include "project.h"
#include "util_export.h"
#include "util_project.h"

/* Compare sheet->hidlib.fullpath to the lreapath() of each string item on the
   config list and returns 1 if there was a match. List items that are relative
   paths are prefixed using prefix if prefix is not NULL. */
static int sheet_on_list(csch_sheet_t *sheet, const rnd_conflist_t *list, const char *prefix)
{
	rnd_conf_listitem_t *item_li;

	/* HACK: use manual ->next looping because list may be an off-config list
	   with broken ->parent */
	for(item_li = rnd_conflist_first((rnd_conflist_t *)list); item_li != NULL; item_li = item_li->link.next) {
		if (item_li->type == RND_CFN_STRING) {
			const char *item_path, *item_str = item_li->val.string[0];
			char *preal, *freeme;

			if ((prefix == NULL) || rnd_is_path_abs(item_str)) {
				freeme = NULL;
				item_path = item_str;
			}
			else
				item_path = freeme = rnd_concat(prefix, "/", item_str, NULL);

			preal = rnd_lrealpath(item_path);
			free(freeme);

			if (preal != NULL) {
				int res = strcmp(sheet->hidlib.fullpath, preal);
				free(preal);
				if (res == 0)
					return 1;
			}
			else
				free(preal);
		}
		
	}
	return 0;
}

void csch_sheet_type_detect(csch_sheet_t *sheet, const rnd_conflist_t *roots, const rnd_conflist_t *aux)
{
	char prjdir[CSCH_PATH_MAX], *prefix = NULL;

	sheet->stype = CSCH_SHTY_unknown;

	if (sheet->hidlib.project == NULL)
		return;

	if (sheet->hidlib.project->fullpath != NULL) {
		int len = strlen(sheet->hidlib.project->fullpath);

		memcpy(prjdir, sheet->hidlib.project->fullpath, len+1);
		if ((len > 11) && (strcmp(prjdir + len-11, "project.lht") == 0))
			prjdir[len-12] = '\0';
		prefix = prjdir;
	}

	if (sheet_on_list(sheet, roots, prefix)) {
		sheet->stype = CSCH_SHTY_ROOT;
		return;
	}

	if (sheet_on_list(sheet, aux, prefix)) {
		sheet->stype = CSCH_SHTY_AUX;
		return;
	}

	sheet->stype = CSCH_SHTY_UNLISTED;
}


int csch_project_is_partial(csch_project_t *prj)
{
	long n, root_sheets = 0;

	for(n = 0; n < prj->hdr.designs.used; n++) {
		csch_sheet_t *sheet = prj->hdr.designs.array[n];
		if (sheet->stype == CSCH_SHTY_ROOT)
			root_sheets++;
	}

	/* rnd_trace("prj partial: counted %ld want %ld\n", root_sheets, prj->num_root_sheets); */

	return root_sheets != prj->num_root_sheets;
}

