# enable siteconfig content only if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG)]} {

# force stderr terminal attachement state
proc initStateIsStderrTty {} {
   return 1
}

# enable debug mode if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_DEBUG)]} {
   set asked_verbosity debug
}

# call a non-existent procedure to raise error if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BROKEN)]} {
   unk_foo
}

# redefine existing modulecmd.tcl procedure to make it broken
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BROKEN2)]} {
   proc lappendState {state val} {
     unk_foo
   }
}

# unset existing modulecmd.tcl procedure
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BROKEN3)]} {
   rename ::lappendState {}
}

# generate error with parseAccessIssue generic msg if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_ACCESSERR)]} {
   set errorCode "Custom error code"
   error [parseAccessIssue "foo"]
}

# try element list display in terse+numbered mode if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TERSENUM)]} {
   displayElementList test {} terse 1 1 [list elt1 elt2 elt3]
}

# try element list display with a tricky list that triggers unusual condition in displayElementList proc
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TRICKYLISTDISP)]} {
   # set a specific terminal column number to fall in tricky condition
   set orig_term_columns [getState term_columns]
   setState term_columns 80
   set max_len 0
   foreach elt [list abc/def abcdefgh/ijklmnop abc/defg abcd/ef abc/defg-hijkl.mn.op abcdefgh/ijklm.nopqrst abcdefg/hijklmnop-qr.st.uvw abcdefgh/ijklmnopqrst-u-vwxy.zA-BCD-E abcdef/ghijklm-nopq.r_st.uv abcdefgh/ijklmnop-q-rstu.vw-xyz-A abcdefg/hijklmn-op.qr.stu abcdefg/hijkl-mn.op.qrs abcd/efgh-ij.k abcdefg/hijk-lmnop_qr.st.uvw abcdef/ghijklmno-p.q.r abcdefgh/ijklmn-o-pqrs.tu abcdefgh/ijklmnop-q-rstu.vw-xyz abcdefg/hij-klm.nopq abcdefg/hij-kl.mn.opq abcdefgh/ijklmnopq_rstuv-w-xyzA.BC-DEF abcdefgh/ijklmnopqrstuv-w-xyzA.BC abcdefgh/ij-k-lmno.pq abcdefgh/ijk-l-mnop.qr-stu abcdefgh/ijklmnop-qr.st abcdef/ghijklmno-pq.rs abcdef/ghi-jklm_no_pqrstuv abcdefgh/ijk-lm-n-opqr.st abcdefgh/ijklm-n-opqr.st-uvw abcdef/ghijklm-nopq_r abcdefg/hijkl-mn.op.qzs abcdefg/hijklmn-op.qr.stz abcdefgh/ijklmn] {
      lappend display_list $elt
      lappend len_list [string length $elt]
      if {[string length $elt] > $max_len} {
         set max_len [string length $elt]
      }
   }
   displayElementList test {} terse 0 1 $display_list $len_list $max_len
   setState term_columns $orig_term_columns
}


# try reading file content without error message on failure if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_READMODNOREPORT)]} {
   readModuleContent "/path/to/unexistent/file"
}

# use loaded module accessor on non-loaded module if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_LMACCESSOR)]} {
   report [getModulefileFromLoadedModule "foo"]
   report [getModuleFromLoadedModulefile "/path/to/foo"]
   report [getModuleFromLoadingModulefile "/path/to/foo"]
   # also check getLoadedConflict in non-serialized mode
   set ::g_loadedModuleConflict(foo) [list bar1 bar2]
   report [getLoadedConflict foo]
   unset ::g_loadedModuleConflict(foo)
}

# fake Solaris stty if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_SOLARIS_STTY)]} {
   set tcl_platform(os) "SunOS"
   set env(PATH) "$env(TESTSUITEDIR):$env(PATH)"
}

# fake Windows mode if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_WINDOWS_MODE)]} {
   set tcl_platform(os) "Windows NT"
   set env(PATH) "$env(TESTSUITEDIR):$env(PATH)"
}

# fake Windows platform if following environment variable is set
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_WINDOWS_PLATFORM)]} {
   set tcl_platform(platform) "windows"
}

# test getDiffBetweenList procedure with element of second list arg not in first list arg
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_GETDIFFBETWEENLIST)]} {
   report [getDiffBetweenList [list same foo foo2] [list same bar bar2]]
}

# test twice calls to getConf term_background and getConf colors procedures
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TWICEINITCOLORS)]} {
    getConf term_background
    getConf term_background
    getConf colors
    getConf colors
}

# test clear sub-command confirmation message without waiting indefinitely
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_EXITONGETSSTDIN)]} {
    rename ::gets ::__gets
    proc gets {fid} {
        if {$fid eq {stdin}} {
            exit 0
        } else {
            return [__gets $fid]
        }
    }
}

# test extra siteconfig disablement
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_NOEXTRASITECONFIG)]} {
    lappendConf locked_configs extra_siteconfig
}

# test Tcl ext lib load by a Tcl interpreter < 8.4
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBLOAD83)]} {
    # call an external Tcl shell to just attempt to load lib in it (as
    # modulecmd.tcl is not compatible with Tcl<8.4)
    exec ./tclsh83 << "load [getConf tcl_ext_lib] Envmodules"
}

# test tcl ext lib procedures against erroneous calls
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBBADCALL)]} {
    set badcalllist [list readFile {readFile foo bar} {readFile foo 0 bar}\
        {readFile foo 0 0 0} getFilesInDirectory {getFilesInDirectory foo bar}]
    foreach badcall $badcalllist {
        if {[catch {[eval $badcall]} errMsg]} {
            reportError $errMsg
        }
    }
}

# test tcl ext lib procedures against a failed closedir call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDCLOSEDIR)]} {
    if {[catch {[getFilesInDirectory $env(TESTSUITEDIR)/modulefiles 0]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures against a failed getpwduid call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDGETPWUID)]} {
    if {[catch {[initStateUsername]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures against a failed getgroups call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDGETGROUPS)]} {
    if {[catch {[initStateUsergroups]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures against a zero result getgroups call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIB0GETGROUPS)]} {
    report [initStateUsergroups]
}

# test tcl ext lib procedures against a duplicate entries in result getgroups call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBDUPGETGROUPS)]} {
    report [initStateUsergroups]
}

# test tcl ext lib procedures against a failed getgrgid call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDGETGRGID)]} {
    if {[catch {[initStateUsergroups]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures against a failed time call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDTIME)]} {
    if {[catch {[initStateClockSeconds]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures called without argument
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_PARSEDATETIMEARG_NOARG)]} {
    if {[catch {[parseDateTimeArg]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures against a failed mktime call
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_TCLEXTLIBFAILEDMKTIME)]} {
    if {[catch {[parseDateTimeArg --before 2020-09-18]} errMsg]} {
        reportError $errMsg
    }
}

# test tcl ext lib procedures called with badly formatted date
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_PARSEDATETIMEARG_BADDATE)]} {
    if {[catch {[parseDateTimeArg --before 2020-09-19U20:00]} errMsg]} {
        reportError $errMsg
    }
}

# specific tests to improve modEq procs coverage
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_MODEQ)]} {
    # matchin tests
    report [modEqProc oo/bar foo/bar matchin 1]
    report [modEqProc aa foo/bar matchin 1]
    report [modEqProc oo/* foo/bar matchin 1]
    report [modEqProcIcase Oo/bar foo/bar matchin 1]
    report [modEqProcIcase Aa foo/bar matchin 1]
    report [modEqProcIcase Oo/* foo/bar matchin 1]
    report [modEqProcExtdfl oo/bar foo/bar matchin 1]
    report [modEqProcExtdfl aa foo/bar matchin 1]
    report [modEqProcExtdfl oo/* foo/bar matchin 1]
    report [modEqProcIcaseExtdfl Oo/bar foo/bar matchin 1]
    report [modEqProcIcaseExtdfl Aa foo/bar matchin 1]
    report [modEqProcIcaseExtdfl Oo/* foo/bar matchin 1]
    defineParseModuleSpecificationProc [getConf advanced_version_spec]
    parseModuleSpecification 0 foo@1.1:1.3
    parseModuleSpecification 0 oo@1.1:1.3
    parseModuleSpecification 0 Oo@1.1:1.3
    parseModuleSpecification 0 fOo@1.1:1.3
    defineModVersCmpProc 0 0
    report [modEqProc oo@1.1:1.3 foo/1.2 matchin]
    report [modEqProc oo@1.1:1.3 foo/1.4 matchin]
    report [modEqProc foo@1.1:1.3 fooo/1.3 matchin]
    defineModVersCmpProc 1 0
    report [modEqProcIcase Oo@1.1:1.3 foo/1.2 matchin]
    report [modEqProcIcase Oo@1.1:1.3 foo/1.4 matchin]
    report [modEqProcIcase fOo@1.1:1.3 fooo/1.3 matchin]
    defineModVersCmpProc 0 1
    report [modEqProcExtdfl oo@1.1:1.3 foo/1.2.2 matchin]
    report [modEqProcExtdfl oo@1.1:1.3 foo/1.4.5 matchin]
    report [modEqProcExtdfl foo@1.1:1.3 fooo/1.3.1 matchin]
    defineModVersCmpProc 1 1
    report [modEqProcIcaseExtdfl Oo@1.1:1.3 foo/1.2.2 matchin]
    report [modEqProcIcaseExtdfl Oo@1.1:1.3 foo/1.4.5 matchin]
    report [modEqProcIcaseExtdfl fOo@1.1:1.3 fooo/1.3.1 matchin]
    parseModuleSpecification 0 foo?bar@1.1:1.3
    parseModuleSpecification 0 o?bar@1.1:1.3
    parseModuleSpecification 0 fOo?bAr@1.1:1.3
    parseModuleSpecification 0 o?bAr@1.1:1.3
    defineModVersCmpProc 0 0
    report [modEqProc foo?bar@1.1:1.3 foo?bar/1.2 matchin]
    report [modEqProc o?bar@1.1:1.3 foo?bar/1.4 matchin]
    report [modEqProc o?bar@1.1:1.3 foo?bar/1.3 matchin]
    defineModVersCmpProc 1 0
    report [modEqProcIcase fOo?bAr@1.1:1.3 foo?bar/1.2 matchin]
    report [modEqProcIcase o?bAr@1.1:1.3 foo?bar/1.4 matchin]
    report [modEqProcIcase o?bAr@1.1:1.3 foo?bar/1.3 matchin]
    defineModVersCmpProc 0 1
    report [modEqProcExtdfl foo?bar@1.1:1.3 foo?bar/1.2.2 matchin]
    report [modEqProcExtdfl o?bar@1.1:1.3 foo?bar/1.4.5 matchin]
    report [modEqProcExtdfl o?bar@1.1:1.3 foo?bar/1.3.1 matchin]
    defineModVersCmpProc 1 1
    report [modEqProcIcaseExtdfl fOo?bAr@1.1:1.3 foo?bar/1.2.2 matchin]
    report [modEqProcIcaseExtdfl o?bAr@1.1:1.3 foo?bar/1.4.5 matchin]
    report [modEqProcIcaseExtdfl o?bAr@1.1:1.3 foo?bar/1.3.1 matchin]
}

if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_REDEFONTHEFLYPROCS)]} {
    defineModStartNbProc 0
    defineModEqProc 0 0
    report [modStartNb foo bar]
    report [modStartNb foo foo]
    report [modStartNb foo fOo]
    defineModStartNbProc 0
    defineModEqProc 0 0
    report [modStartNb foo bar]
    report [modStartNb foo foo]
    report [modStartNb foo fOo]
    defineModStartNbProc 1
    defineModEqProc 1 1
    report [modStartNb foo bar]
    report [modStartNb foo foo]
    report [modStartNb foo fOo]
    defineModStartNbProc 1
    defineModEqProc 1 1
    report [modStartNb foo bar]
    report [modStartNb foo foo]
    report [modStartNb foo fOo]
    defineModVersCmpProc 0 0
    report [modVersCmp in {{eq foo}} foo eqstart]
    report [modVersCmp in {{eq foo}} bar eqstart]
    report [modVersCmp in {{eq foo}} fOo eqstart]
    defineModVersCmpProc 0 0
    report [modVersCmp in {{eq foo}} foo eqstart]
    report [modVersCmp in {{eq foo}} bar eqstart]
    report [modVersCmp in {{eq foo}} fOo eqstart]
    defineModVersCmpProc 1 1
    report [modVersCmp in {{eq foo}} foo eqstart]
    report [modVersCmp in {{eq foo}} bar eqstart]
    report [modVersCmp in {{eq foo}} fOo eqstart]
    defineModVersCmpProc 1 1
    report [modVersCmp in {{eq foo}} foo eqstart]
    report [modVersCmp in {{eq foo}} bar eqstart]
    report [modVersCmp in {{eq foo}} fOo eqstart]
    defineModEqProc 0 0
    report [modEq foo foo equal]
    report [modEq foo bar equal]
    report [modEq foo fOo equal]
    defineModEqProc 0 0
    report [modEq foo foo equal]
    report [modEq foo bar equal]
    report [modEq foo fOo equal]
    defineModEqProc 1 1
    report [modEq foo foo equal]
    report [modEq foo bar equal]
    report [modEq foo fOo equal]
    defineModEqProc 1 1
    report [modEq foo foo equal]
    report [modEq foo bar equal]
    report [modEq foo fOo equal]
}

# specific tests to improve formatErrStackTrace proc coverage
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_FORMATERRSTACKTRACE)]} {
    set errmsg {error message
    while executing
foo call
    invoked from within
foo
    (file "foo")}

    report [formatErrStackTrace $errmsg foo]
}

# produce an unknown error in a modulecmd.tcl procedure during a modulefile evaluation
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_UNKINTERRDURINGMODEVAL)]} {
    proc getModshareVarName {var} {
        foo
    }
}

# set a bad value for tag_abbrev default value
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BADTAGABBREVDFLVALUE)]} {
    set g_config_defs(tag_abbrev) {MODULES_TAG_ABBREV {loaded} 0 {} {} initConfTagAbbrev}
}

# set a bad value for variant_shortcut default value
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BADVARIANTSHORTCUTDFLVALUE)]} {
    set g_config_defs(variant_shortcut) {MODULES_VARIANT_SHORTCUT {foo} 0 {} {} initConfVariantShortcut}
}

# specific tests to improve getModuleDesignation procs coverage
if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_GETMODULEDESIGNATION)]} {
    # test disabled sgr mode
    cacheCurrentModules
    report [getModuleDesignation loaded variant/1.0 0]
}

}
