/*
  Initialization script for s2sh. If it is named the same as the binary
  (minus any ".exe" extension), with a ".s2" extension (and in the same directory),
  s2sh will autoload this file at startup and fail if processing it fails.
*/

assert Fossil;
assert Fossil.Context;

assert s2 && 'function' === typename s2.loadModule;
/**
  An s2.loadModule() proxy which uses a PathFinder
  instance to search for DLLs. The name argument must be the
  base name part, optionally with a partial leading (sub-)path.

  The dest argument is passed as the last argument to s2.loadModule(),
  and is returned to the caller on success. Well-behaved modules will
  install their features in that object.

  If the S2_MODULE_PATH and/or S2_MODULE_EXTENSION environment
  variables are set, they are treated as a semicolon- or
  colon-separated list of directories resp. file extensions. If not
  specified, some default set is used.

*/
s2.loadModule2 = function(name, dest = {}){
    affirm 'string' === typename name;
    const fn = pf.search( name );
    fn || throw "Cannot find '".
        concat(name, "' in search path ", pf.prefix.toJSONString());
    //print("Importing",name, '==>', fn);
    return loadModule.call(this, realpath ? realpath(fn) : fn, dest);
}.importSymbols({
    loadModule: s2.loadModule,
    realpath: s2.io ? s2.io.realpath : undefined,
    pf: s2.PathFinder.new(
        // Directories...
        ('string' === typename (var s = s2.getenv('S2_MODULE_PATH')))
            ? s.split(s.indexOf(';') >= 0 ? ';' : ':')
        : ['.'],
        // Extensions...
        ('string' === typename (s = s2.getenv('S2_MODULE_EXTENSIONS')))
       ? s.split(s.indexOf(';') >= 0 ? ';' : ':')
        : ['.so','.dll']
    )
});

assert 'function' === typename s2.import;
/**
  An s2.import() extension which uses a configable
  search path and extension set for scripts.
*/
s2.import2 = function(name){
    affirm 'string' === typename name;
    const fn = pf.search( name );
    fn || throw "Cannot find '".
        concat(name, "' in search path ", pf.prefix.toJSONString());
    return import.call(this, realpath ? realpath(fn) : fn);
}.importSymbols({
    import: s2.import,
    realpath: s2.io ? s2.io.realpath : undefined,
    pf: s2.PathFinder.new(
        // Directories...
        ('string' === typename (var s = s2.getenv('S2_INCLUDES_PATH')))
            ? s.split(s.indexOf(';') >= 0 ? ';' : ':')
        : ['.'],
        // Extensions...
      ('string' === typename (s = s2.getenv('S2_INCLUDES_EXTENSIONS')))
            ? s.split(s.indexOf(';') >= 0 ? ';' : ':')
        : ['.s2']
    )
});


s2.vls = proc(v){
    if(!s2.isDerefable(v)) return;
    this.eachProperty.call(v,eachProp);
}.importSymbols({
    eachProp:proc(k,v){
        print(typename k, k, '=', typename v, v);
    }
});

/**
   Add Fossil.require(), used in loading Fossil-aware modules.
*/
Fossil.require = s2.import2( 'require.d/require.s2' );

// The rest of the initialization happens via here:
Fossil.require(['nocache!fsl/extendFossil'],proc(){});
