/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2026
 *					All rights reserved
 *
 *  This file is part of GPAC / common tools sub-project
 *
 *  GPAC 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, or (at your option)
 *  any later version.
 *
 *  GPAC 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; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "module_wrap.h"
#include <gpac/config_file.h>
#include <gpac/tools.h>
#include <gpac/network.h>



#ifndef GPAC_MODULE_CUSTOM_LOAD
static void load_all_modules(GF_ModuleManager *mgr)
{
#define LOAD_PLUGIN(	__name	)	{ \
	GF_InterfaceRegister *gf_register_module_##__name();	\
	pr = gf_register_module_##__name();\
	if (!pr) {\
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically load module ##__name\n"));\
	} else {\
		gf_list_add(mgr->plugin_registry, pr);	\
	}	\
	}

#ifdef GPAC_STATIC_MODULES
	GF_InterfaceRegister *pr;

#ifdef GPAC_HAS_SDL
	LOAD_PLUGIN(sdl_out);
#endif

#if defined(GPAC_HAS_FREETYPE) && !defined(GPAC_DISABLE_EVG)
	LOAD_PLUGIN(ftfont);
#endif
#ifdef GPAC_HAS_ALSA
	LOAD_PLUGIN(alsa);
#endif

#ifdef GPAC_HAS_DIRECTFB
	LOAD_PLUGIN(directfb_out);
#endif

#ifdef GPAC_HAS_DIRECTX
	LOAD_PLUGIN(dx_out);
#endif

#ifdef GPAC_HAS_JACK
	LOAD_PLUGIN(jack);
#endif

#ifdef GPAC_HAS_OSS
	LOAD_PLUGIN(oss);
#endif

#ifdef GPAC_HAS_PULSEAUDIO
	LOAD_PLUGIN(pulseaudio);
#endif

#ifndef GPAC_DISABLE_COMPOSITOR
	LOAD_PLUGIN(validator);
#endif


#ifdef GPAC_HAS_WAVEOUT
	LOAD_PLUGIN(wave_out);
#endif

#ifdef GPAC_HAS_X11
	LOAD_PLUGIN(x11_out);
#endif

	//todo fix project for iOS
#ifdef GPAC_CONFIG_IOS
	//these do not compile with xcode 4.2
//    LOAD_PLUGIN(ios_cam);
//    LOAD_PLUGIN(ios_mpegv);
#endif

#endif //GPAC_STATIC_MODULES

#undef LOAD_PLUGIN

}
#endif //GPAC_MODULE_CUSTOM_LOAD

GF_ModuleManager *gpac_modules_static = NULL;

GF_EXPORT
GF_Err gf_module_load_static(GF_InterfaceRegister *(*register_module)())
{
	GF_InterfaceRegister *pr;
	GF_Err rc;
	if (register_module == NULL)
		return GF_OK;

	pr = register_module();
	if (!pr) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically loaded module\n"));
		return GF_NOT_SUPPORTED;
	}

	rc = gf_list_add(gpac_modules_static->plugin_registry, pr);
	if (rc != GF_OK) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically loaded module\n"));
		return rc;
	}
	return GF_OK;
}

u32 gf_modules_refresh(GF_ModuleManager *pm);

static void gf_modules_check_load()
{
	if (gpac_modules_static->needs_load) {
		gpac_modules_static->needs_load = GF_FALSE;
#ifndef GPAC_MODULE_CUSTOM_LOAD
		load_all_modules(gpac_modules_static);
#endif
		gf_modules_refresh(gpac_modules_static);
		GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Loaded %d modules.\n", gf_modules_count() ));
	}
}


void gf_modules_refresh_module_directories()
{
	char* directories;
	char* tmp_dirs;
	char * pch;
	u32 i;
	GF_ModuleManager *pm = gpac_modules_static;
	if (!pm) return;

	for (i=0; i<pm->num_dirs; i++) {
		gf_free(pm->dirs[i]);
	}
	pm->num_dirs = 0;

	//default module directory
	directories = (char*)gf_opts_get_key("core", "module-dir");
	if (directories) {
		pm->dirs[0] = gf_strdup(directories);
		pm->num_dirs = 1;
	}

	/* User-defined directories*/
	directories = (char*)gf_opts_get_key("core", "mod-dirs");
	if (! directories) {
		if (!pm->num_dirs) {
#ifndef GPAC_CONFIG_IOS
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Modules directories not found - check the \"module-dir\" key is set in the \"core\" section\n"));
#endif
		}
		return;
	}

	tmp_dirs = directories;
	pch = strtok (tmp_dirs,";");

	while (pch != NULL) {
		if (pm->num_dirs == MAX_MODULE_DIRS) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Reach maximum number of module directories %d.\n", MAX_MODULE_DIRS));
			break;
		}
		pm->dirs[pm->num_dirs] = gf_strdup(pch);
		pm->num_dirs++;
		pch = strtok (NULL, ";");
	}
}


/*!
\brief module manager construtcor
 *
 *Constructs a module manager object.
\param config GPAC configuration file handle. If this is NULL, the modules won't be able to share the configuration
 *file with the rest of the GPAC framework.
*/
void gf_modules_new(GF_Config *config)
{
	const char *opt;
	if (!config) return;
	if (gpac_modules_static) return;

	/* Try to resolve directory from config file */
	GF_SAFEALLOC(gpac_modules_static, GF_ModuleManager);
	if (!gpac_modules_static) return;
	gpac_modules_static->cfg = config;
	gpac_modules_static->mutex = gf_mx_new("Module Manager");
	gf_modules_refresh_module_directories();

	/* Initialize module list */
	gpac_modules_static->plug_list = gf_list_new();
	if (!gpac_modules_static->plug_list) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of modules !!!\n"));
		gf_free(gpac_modules_static);
		gpac_modules_static = NULL;
		return;
	}
	gpac_modules_static->plugin_registry = gf_list_new();
	if (!gpac_modules_static->plugin_registry) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of static module registers !!!\n"));
		gf_list_del(gpac_modules_static->plug_list);
		gf_free(gpac_modules_static);
		gpac_modules_static = NULL;
		return;
	}

	gpac_modules_static->no_unload = !gf_opts_get_bool("core", "mod-reload");

	opt = gf_opts_get_key("core", "version");
	if (!opt || strcmp(opt, gf_gpac_version())) {
		gf_cfg_del_section(config, "PluginsCache");
		gf_opts_set_key("core", "version", gf_gpac_version());
	}

	gpac_modules_static->needs_load = GF_TRUE;
}


void gf_module_reload_dirs()
{
	if (!gpac_modules_static) return;
	gf_modules_refresh_module_directories();
	gpac_modules_static->needs_load = GF_TRUE;
}


/*!
\brief module manager destructor
 *
 *Destroys the module manager
 */
void gf_modules_del()
{
	u32 i;
	GF_ModuleManager *pm = gpac_modules_static;
	if (!pm) return;

	gpac_modules_static = NULL;

	/*unload all modules*/
	while (gf_list_count(pm->plug_list)) {
		ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, 0);
		gf_modules_free_module(inst);
		gf_list_rem(pm->plug_list, 0);
	}
	gf_list_del(pm->plug_list);

	/* Delete module directories*/
	for (i = 0; i < pm->num_dirs; i++) {
		gf_free((void*)pm->dirs[i]);
	}

	/*remove all static modules registry*/
	while (gf_list_count(pm->plugin_registry)) {
		GF_InterfaceRegister *reg  = (GF_InterfaceRegister *) gf_list_get(pm->plugin_registry, 0);
		gf_free(reg);
		gf_list_rem(pm->plugin_registry, 0);
	}

	if (pm->plugin_registry) gf_list_del(pm->plugin_registry);
	gf_mx_del(pm->mutex);
	gf_free(pm);
}

Bool gf_module_is_loaded(GF_ModuleManager *pm, char *filename)
{
	u32 i = 0;
	ModuleInstance *inst;
	while ( (inst = (ModuleInstance *) gf_list_enum(pm->plug_list, &i) ) ) {
		if (!strcmp(inst->name, filename)) return GF_TRUE;
	}
	return GF_FALSE;
}

GF_EXPORT
u32 gf_modules_count()
{
	if (!gpac_modules_static) return 0;
	gf_modules_check_load();
	return gf_list_count(gpac_modules_static->plug_list);
}


GF_EXPORT
GF_BaseInterface *gf_modules_load(u32 whichplug, u32 InterfaceFamily)
{
	const char *opt;
	char szKey[32];
	ModuleInstance *inst;
	GF_BaseInterface *ifce;
	GF_ModuleManager *pm = gpac_modules_static;

	if (!pm) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : No Module Manager set\n"));
		return NULL;
	}

	gf_mx_p(pm->mutex);

	gf_modules_check_load();

	inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug);
	if (!inst) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : no module %d exist.\n", whichplug));
		gf_mx_v(pm->mutex);
		return NULL;
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface...%s\n", inst->name));
	/*look in cache*/
	if (!pm->cfg) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] No pm->cfg has been set !!!\n"));
		gf_mx_v(pm->mutex);
		return NULL;
	}
	opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name);
	if (opt) {
		const char * ifce_str = gf_4cc_to_str(InterfaceFamily);
		snprintf(szKey, 32, "%s:yes", ifce_str ? ifce_str : "(null)");
		if (!strstr(opt, szKey)) {
			//cleanup if version changed
			szKey[3] = 0;
			char *val = strstr(opt, szKey);
			if (val && !strncmp(val+4, ":yes", 4)) {
				gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, NULL);
			} else {
				gf_mx_v(pm->mutex);
				return NULL;
			}
		}
	}
	if (!gf_modules_load_library(inst)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name));
		gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
		gf_mx_v(pm->mutex);
		return NULL;
	}
	if (!inst->query_func) {
		if (!inst->filterreg_func) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Library %s missing GPAC export symbols\n", inst->name));
			gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
		}
		goto err_exit;
	}

	/*build cache*/
	if (!opt) {
		u32 i;
		const int maxKeySize = 32;
		Bool found = GF_FALSE;
		char *key;
		const u32 *si = inst->query_func();
		if (!si) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[Core] GPAC module %s has no supported interfaces - disabling\n", inst->name));
			gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
			goto err_exit;
		}
		i=0;
		while (si[i]) i++;

		key = NULL;
		i=0;
		while (si[i]) {
			snprintf(szKey, maxKeySize, "%s:yes ", gf_4cc_to_str(si[i]));
			gf_dynstrcat(&key, szKey, NULL);
			if (InterfaceFamily==si[i]) found = GF_TRUE;
			i++;
		}
		gf_dynstrcat(&key, inst->filterreg_func ? "GFR1:yes" : "GFR1:no", NULL);

		gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, key);
		gf_free(key);
		if (!found) goto err_exit;
	}

	if (!inst->load_func) goto err_exit;
	ifce = (GF_BaseInterface *) inst->load_func(InterfaceFamily);
	/*sanity check*/
	if (!ifce) goto err_exit;
	if (!ifce->module_name || (ifce->InterfaceType != InterfaceFamily)) {
		inst->destroy_func(ifce);
		goto err_exit;
	}
	gf_list_add(inst->interfaces, ifce);
	/*keep track of parent*/
	ifce->HPLUG = inst;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s DONE.\n", inst->name));
	gf_mx_v(pm->mutex);
	return ifce;

err_exit:
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s exit label, freeing library...\n", inst->name));
	gf_modules_unload_library(inst);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s EXIT.\n", inst->name));
	gf_mx_v(pm->mutex);
	return NULL;
}

void *gf_modules_load_filter(u32 whichplug, void *fsess)
{
	const char *opt;
	ModuleInstance *inst;
	void *freg = NULL;
	GF_ModuleManager *pm = gpac_modules_static;
	if (!pm) return NULL;
	gf_modules_check_load();

	inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug);
	if (!inst) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : no module %d exist.\n", whichplug));
		return NULL;
	}
	if (strncmp(inst->name, "gf_", 3))
		return NULL;
	opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name);
	if (opt) {
		if (!strcmp(opt, "invalid")) return NULL;
		if (!strstr(opt, "GFR1:yes")) return NULL;
	}
	if (!gf_modules_load_library(inst)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name));
		gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
		return NULL;
	}
	freg = NULL;
	if (inst->filterreg_func) {
		freg = inst->filterreg_func(fsess);
	}
	if (!freg) {
		gf_modules_unload_library(inst);
	}
	return freg;
}

GF_EXPORT
GF_BaseInterface *gf_modules_load_by_name(const char *plug_name, u32 InterfaceFamily, Bool rebrowse_all)
{
	const char *file_name;
	u32 i, count;
	GF_BaseInterface *ifce;
	GF_ModuleManager *pm = gpac_modules_static;
	if (!pm || !plug_name || !pm->plug_list || !pm->cfg) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load_by_name has bad parameters pm=%p, plug_name=%s.\n", pm, plug_name));
		return NULL;
	}

	gf_modules_check_load();

	count = gf_list_count(pm->plug_list);
	/*look for cache entry*/
	file_name = gf_cfg_get_key(pm->cfg, "PluginsCache", plug_name);

	if (file_name) {

		for (i=0; i<count; i++) {
			ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, i);
			if (!rebrowse_all && !strcmp(inst->name,  file_name)) {
				ifce = gf_modules_load(i, InterfaceFamily);
				if (ifce) return ifce;
			}
		}
	}

	GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Plugin %s of type %d not found in cache, searching for it...\n", plug_name, InterfaceFamily));
	for (i=0; i<count; i++) {
		const char *mod_filename;
		if (!rebrowse_all) {
			ModuleInstance *inst = (ModuleInstance *) gf_list_get(gpac_modules_static->plug_list, i);
			if (inst->name && strcmp(inst->name, plug_name)) continue;
		}
		ifce = gf_modules_load(i, InterfaceFamily);
		if (!ifce) continue;
		if (ifce->module_name && !strcmp(ifce->module_name, plug_name) ) {
			/*update cache entry*/
			gf_cfg_set_key(pm->cfg, "PluginsCache", plug_name, ((ModuleInstance*)ifce->HPLUG)->name);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Added plugin cache %s for %s\n", plug_name, ((ModuleInstance*)ifce->HPLUG)->name));
			return ifce;
		}
		/*check direct addressing by dynamic lib name*/
		mod_filename = gf_module_get_file_name(ifce);
		if (mod_filename && strstr(mod_filename, plug_name)) {
			return ifce;
		}
		gf_modules_close_interface(ifce);
	}
	GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Plugin %s not found in %d modules.\n", plug_name, count));
	return NULL;
}

GF_EXPORT
GF_Err gf_modules_close_interface(GF_BaseInterface *ifce)
{
	ModuleInstance *par;
	s32 i;
	if (!ifce) return GF_BAD_PARAM;
	par = (ModuleInstance *) ifce->HPLUG;

	if (!par || !ifce->InterfaceType) return GF_BAD_PARAM;

	i = gf_list_find(par->plugman->plug_list, par);
	if (i<0) return GF_BAD_PARAM;

	i = gf_list_find(par->interfaces, ifce);
	if (i<0) return GF_BAD_PARAM;
	gf_list_rem(par->interfaces, (u32) i);
	par->destroy_func(ifce);
	gf_modules_unload_library(par);
	//GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] interface %s unloaded\n", ifce->module_name));
	return GF_OK;
}

GF_EXPORT
const char *gf_modules_get_file_name(u32 i)
{
	ModuleInstance *inst = (ModuleInstance *) gf_list_get(gpac_modules_static->plug_list, i);
	if (!inst) return NULL;
	return inst->name;
}

GF_EXPORT
const char *gf_module_get_file_name(GF_BaseInterface *ifce)
{
	ModuleInstance *inst = (ModuleInstance *) ifce->HPLUG;
	if (!inst) return NULL;
	return inst->name;
}

#include <gpac/modules/video_out.h>
#include <gpac/modules/audio_out.h>
#include <gpac/modules/font.h>
static Bool module_check_ifce(GF_BaseInterface *ifce, u32 ifce_type)
{
	switch (ifce_type) {
	case GF_VIDEO_OUTPUT_INTERFACE:
	{
		GF_VideoOutput *vout = (GF_VideoOutput *) ifce;
		if (!vout || !vout->Flush || !vout->Setup) return GF_FALSE;
		return GF_TRUE;
	}
	case GF_AUDIO_OUTPUT_INTERFACE:
	{
		GF_AudioOutput *aout = (GF_AudioOutput *) ifce;
		if (!aout || !aout->Configure || !aout->Setup) return GF_FALSE;
		//no more support for raw out, deprecated
		if (!stricmp(ifce->module_name, "Raw Audio Output")) return GF_FALSE;
		/*check that's a valid audio mode*/
		if ((aout->SelfThreaded && aout->SetPriority) || aout->WriteAudio)
			return GF_TRUE;
		return GF_FALSE;
	}

	default:
		return GF_TRUE;
	}
}


GF_BaseInterface *gf_module_load(u32 ifce_type, const char *name)
{
	GF_BaseInterface *ifce = NULL;
	if (name) {
		ifce = gf_modules_load_by_name(name, ifce_type, GF_TRUE);
		if (!module_check_ifce(ifce, ifce_type)) {
			gf_modules_close_interface(ifce);
			ifce = NULL;
		}
	}
	/*get a preferred output*/
	if (!ifce) {
		const char *sOpt;
		switch (ifce_type) {
		case GF_VIDEO_OUTPUT_INTERFACE:
			sOpt = gf_opts_get_key("core", "video-output");
			break;
		case GF_AUDIO_OUTPUT_INTERFACE:
			sOpt = gf_opts_get_key("core", "audio-output");
			break;
		case GF_FONT_READER_INTERFACE:
			sOpt = gf_opts_get_key("core", "font-reader");
			break;
		default:
			sOpt = NULL;
		}
		if (sOpt) {
			ifce = gf_modules_load_by_name(sOpt, ifce_type, GF_TRUE);
			if (!module_check_ifce(ifce, ifce_type)) {
				gf_modules_close_interface(ifce);
				ifce = NULL;
			}
		}
	}
	if (!ifce) {
		u32 i, count = gf_modules_count();
		for (i=0; i<count; i++) {
			ifce = gf_modules_load(i, ifce_type);
			if (!ifce) continue;

			if (!module_check_ifce(ifce, ifce_type)) {
				gf_modules_close_interface(ifce);
				ifce = NULL;
				continue;
			}
			return ifce;
		}
	}
	return ifce;
}

Bool module_args_used = GF_FALSE;

GF_EXPORT
const char *gf_module_get_key(GF_BaseInterface *dr, char *key_name)
{
	if (!dr || !dr->module_name || !dr->args) return NULL;

	u32 klen = (u32) strlen(key_name);
	u32 i=0, nb_args = gf_sys_get_argc();
	Bool found = GF_FALSE;
	const char *res = NULL;
	while (dr->args[i].name) {
		if (!strcmp(dr->args[i].name, key_name)) {
			res = gf_opts_get_key(dr->module_name, key_name);
			if (!res)
				res = dr->args[i].val;
			found = GF_TRUE;
		}
		i++;
	}
	if (!found) return NULL;
	for (i=0; i<nb_args; i++) {
		const char *a = gf_sys_get_arg(i);
		if (strncmp(a, "--", 2)) continue;
		a+=2;
		char *msep = strchr(a, '@');
		if (msep) {
			u32 mlen = (u32) (msep-a);
			if (strncmp(dr->module_name, a, mlen)) continue;
			a += mlen+1;
		}
		if (strncmp(a, key_name, klen)) continue;
		if (a[klen] == '=') {
			gf_sys_mark_arg_used(i, GF_TRUE);
			module_args_used=GF_TRUE;
			return a+klen+1;
		}
		if (!a[klen]) {
			module_args_used=GF_TRUE;
			gf_sys_mark_arg_used(i, GF_TRUE);
			return "1";
		}
	}
	return res;
}
GF_EXPORT
Bool gf_module_get_bool(GF_BaseInterface *dr, char *key_name)
{
	const char *res = gf_module_get_key(dr, key_name);
	if (!res) return GF_FALSE;
	if (!stricmp(res, "yes") || !stricmp(res, "true") || !strcmp(res, "1")) return GF_TRUE;
	return GF_FALSE;
}
GF_EXPORT
Bool gf_module_get_int(GF_BaseInterface *dr, char *key_name)
{
	const char *res = gf_module_get_key(dr, key_name);
	if (!res) return 0;
	if (!stricmp(res, "yes") || !stricmp(res, "true") || !strcmp(res, "1")) return atoi(res);
	return 0;
}

