#!/bin/sh -
# Taken from https://github.com/passagemath/passagemath/blob/main/sage#L29
#
# Resolve all symbolic links in a filename.  This more or less behaves
# like "readlink -f" except that it does not convert the filename to an
# absolute path (a relative path remains relative), nor does it treat
# "." or ".." specially.
resolvelinks() {
    # $in is what still needs to be converted (normally has no starting slash)
    in="$1"
    # $out is the part which is converted (normally ends with trailing slash)
    out="./"

    # Move stuff from $in to $out
    while [ -n "$in" ]; do
        # Normalize $in by replacing consecutive slashes by one slash
        in=$(echo "${in}" | sed 's://*:/:g')

        # If $in starts with a slash, remove it and set $out to the root
        in_without_slash=${in#/}
        if [ "$in" != "$in_without_slash" ]; then
            in=$in_without_slash
            out="/"
            continue
        fi

        # Check that the directory $out exists by trying to cd to it.
        # If this fails, then cd will show an error message (unlike
        # test -d "$out"), so no need to be more verbose.
        ( cd "$out" ) || return $?


        # Get the first component of $in
        f=${in%%/*}

        # If it is not a symbolic link, simply move it to $out
        if [ ! -L "$out$f" ]; then
            in=${in#"$f"}
            out="$out$f"

            # If the new $in starts with a slash, move it to $out
            in_without_slash=${in#/}
            if [ "$in" != "$in_without_slash" ]; then
                in=$in_without_slash
                out="$out/"
            fi
            continue
        fi

        # Now resolve the symbolic link "$f"
        f_resolved=`readlink -n "$out$f" 2>/dev/null`
        status=$?
        # status 127 means readlink could not be found.
        if [ $status -eq 127 ]; then
            # We don't have "readlink", try a stupid "ls" hack instead.
            # This will fail if we have filenames like "a -> b".
            fls=`ls -l "$out$f" 2>/dev/null`
            status=$?
            f_resolved=${fls##*-> }

            # If $fls equals $f_resolved, then certainly
            # something is wrong
            if [ $status -eq 0 -a "$fls" = "$f_resolved" ]; then
                echo >&2 "Cannot parse output from ls -l '$out$f'"
                return 1
            fi
        fi
        if [ $status -ne 0 ]; then
            echo >&2 "Cannot read symbolic link '$out$f'"
            return $status
        fi

        # In $in, replace $f by $f_resolved (leave $out alone)
        in="${in#${f}}"
        in="${f_resolved}${in}"
    done

    # Return $out
    echo "$out"
}
exec_prefix=$(resolvelinks "$0")
exec_prefix=${exec_prefix%/*}
exec_prefix=${exec_prefix%/*}
exec_prefix=$(cd $exec_prefix && pwd -P)
FRICAS="${exec_prefix}/lib/fricas/target/x86_64-apple-darwin24.6.0"
export FRICAS
FRICAS_VERSION="1.3.12"
FRICAS_LISP_FLAVOR="ecl"
FRICAS_LISP_VERSION="24.5.10"
ECLDIR=$(ecl --eval "(princ (si:get-library-pathname))" --eval "(quit)")
[ -n "$ECLDIR" ] && export ECLDIR
#!/bin/sh

PATH=$FRICAS/bin:${PATH}:/usr/bin/X11
export PATH

# 0. Basic utilities

showuse() {
  echo "Usage:"
  echo "  fricas [options]"
  echo
  echo "The following options are recognized."
  echo "  -clef | -noclef    use Clef (default: -clef)"
  echo "  -clefprog fname    use named program for Clef"
  echo "  -eval code         evaluate specified code at start"
  echo "  -go   | -nogo      whether to start system"
  echo "  -gr   | -nogr      use Graphics (default: -gr)"
  echo "  -ht   | -noht      use HyperDoc (default: -ht)"
  echo "  -ihere| -noihere   start an interpreter buffer in the original window"
  echo "  -iw   | -noiw      start in interpreter window"
  echo "  -list              list workspaces only"
  echo "  -nox               don't use X Windows"
  echo "  -rl                use GNU Readline via rlwrap if available"
  echo "  -ws wsname         use named workspace"
  #echo "  -grprog fname      use named program for Graphics"
  #echo "  -htprog fname      use named program for HyperDoc"
  #echo "  -sessionprog fname use named program for session"
  #echo "  -clientprog fname  use named program for spadclient"
  echo
  echo "Some options can only be given in the first position."
  echo
  echo "Start only a plain commandline interface."
  echo "  fricas -nosman [-rl] [-eval code]"
  echo
  echo "Print this help screen and exit."
  echo "  fricas --help"
  echo
  echo "Print version information and exit."
  echo "  fricas --version"
  echo
  echo "Setup special frontends."
  echo "  fricas -texmacs"
  echo "  fricas -emacs"
}

ciao() {
    echo "Goodbye."
    exit 1
}

needsubopt () {
    echo "The $1 option requires an argument."
    ciao
}


RLWRAP=${RLWRAP:=rlwrap}
have_rlwrap() {
    if [ -z "$(command -v ${RLWRAP})" ] ; then
	echo "Ignoring -rl option; rlwrap program \"${RLWRAP}\" not found."
	return 1
    fi
    return 0
}

# 1. Ensure the environment is set.

# The aldor compiler is usually expected to be in PATH at the time of
# starting fricas, but, we allow for more flexibility.
# 1) If ALDOR_COMPILER is set, it's assumed to be the absolute path
#    to the aldor compiler executable.
# 2) If there is a program ${exec_prefix}/bin/aldor, then this will
#     be used.
# 3) It's assumed that "aldor" is in PATH.
if [ -z ${ALDOR_COMPILER} ]; then
    if [ -x ${exec_prefix}/bin/aldor ]; then
        ALDOR_COMPILER=${exec_prefix}/bin/aldor
    else
        ALDOR_COMPILER=aldor
    fi
fi
export ALDOR_COMPILER

if [ ! -d "$FRICAS" ] ; then
  echo "The directory for FriCAS, $FRICAS, does not exist."
  ciao
fi

# Name the workspace directories.
rootwsdir=$FRICAS/bin

# 2. Process command line arguments.
algebra_off=')set output algebra off'
texmacs_on=')set output texmacs on'
markers=")lisp (setf |\$ioHook| (lambda (x &optional args) (cond ((eq x '|startPrompt|) (princ (concat (code-char 2) \"prompt\#\") ))  ((eq x '|endOfTeXmacsOutput|) (princ (concat (code-char 5) (code-char 10)))) ((eq x '|startTeXmacsOutput|) (princ (code-char 2)))  ((eq x '|startKeyedMsg|)  (princ (concat (code-char 2) \"verbatim:\")))  ((eq x '|endOfKeyedMsg|)  (princ (code-char 5)))  ((eq x '|endOfPrompt|) (princ (code-char 5) ))  )))"


if [ "$*" = "-texmacs" ] ; then
    exec "$FRICAS/bin/FRICASsys" -- -eval "$algebra_off" -eval "$markers" -eval "$texmacs_on"
fi

# Start FriCAS from inside emacs. Discard output to stderr.
if [ "$*" = "-emacs" ] ; then
    eval "exec $FRICAS/bin/sman -noclef 2>/dev/null"
fi

# Call FRICASsys directly.
if [ "$1" = "-nosman" ] ; then
    shift

    # If -rl option is given, it must come right after -nosman
    if [ "$1" = "-rl" ] ; then
        shift
        if ! have_rlwrap ; then RLWRAP=""; fi
    else
        RLWRAP=""
    fi

    exec $RLWRAP "$FRICAS/bin/FRICASsys" "$@"

    exit 1
fi

# Defaults for command-line arguments.
list=no
go=yes
wsname=FRICASsys

otheropts=""

had_nogr=false
had_noht=false

while [ "$*" != "" ] ; do
    opt=$1
    case $1 in
        -h|--help)
            showuse
            exit 0
            ;;
        --version)
            echo "FriCAS $FRICAS_VERSION"
            echo "based on $FRICAS_LISP_FLAVOR $FRICAS_LISP_VERSION"
            exit 0
            ;;
        -list)
            list=yes
            go=no
            ;;
        -go)
            go=yes
            ;;
        -nogo)
            go=no
            ;;
        -ws)
            if [ "$2" = "" ] ; then needsubopt "$1" ; fi
            shift
            wsname="$1"
            ;;
        -grprog|-htprog|-clefprog|-sessionprog|-clientprog|-paste|-rm|-rv)
            if [ "$2" = "" ] ; then needsubopt "$1" ; fi
            otheropts="$otheropts $1 $2"
            shift
            ;;
        -nogr)
            had_nogr=true
            otheropts="$otheropts $1"
            ;;
        -noht)
            had_noht=true
            otheropts="$otheropts $1"
            ;;
        -nox)
            had_nogr=true
            had_noht=true
            otheropts="$otheropts $1"
            ;;
        -clef|-noclef|-gr|-ht|-iw|-noiw|-ihere|-noihere)
            otheropts="$otheropts $1"
            ;;
        -rl)
	    if have_rlwrap ; then
                otheropts="$otheropts -clefprog ${FRICAS}/bin/fricas-readline"
	    fi
            ;;
        -eval)
            shift
            if [ -z "$*" ] ; then
                echo "Parameter of -eval must be provided with a value"
                ciao
            else
                patt='s,[^A-Za-z0-9],\\&,g'
                npar=`echo "$1" | sed $patt`
                otheropts="$otheropts -eval $npar"
            fi
            ;;
        *)
            echo "Unknown option: $1"
            echo
            showuse
            ciao
            ;;
        esac
        shift
done

if [ $had_nogr != true -a ! -f $FRICAS/lib/viewman ] ; then
    echo "viewman not present, disabling graphics"
    otheropts="$otheropts -nogr"
fi

if [ $had_noht != true -a ! -f $FRICAS/bin/hypertex ]; then
    echo "hypertex not present, disabling HyperDoc"
    otheropts="$otheropts -noht"
fi

# 3. List the available workspaces, if asked

listwspaces()
{
        echo "$1"
        ls -l $2 | grep "sys$"
        echo ""
}

if [ $list = yes ] ; then
    listwspaces "FriCAS workspaces in \$FRICAS/bin = $rootwsdir: " $rootwsdir
fi

# 5. Try to ensure a suitable workspace on this host.

if [ `expr $wsname : '.*/.*'` = 0 ] ; then
        serverws=$rootwsdir/$wsname
else
        serverws=$wsname
fi

if [ ! -f $serverws ] ; then
        showuse
        ciao
fi

# 6. Start processes

if [ $go = no ] ; then
    echo "Would now execute the following."
    echo "FRICAS=\"${exec_prefix}/lib/fricas/target/x86_64-linux-gnu\""
    echo "export FRICAS"
    echo "$FRICAS/bin/sman $otheropts -ws $serverws"
    exit 0
fi

eval "exec $FRICAS/bin/sman $otheropts -ws $serverws"
