#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"
el_make_environment
. gettext.sh
TEXTDOMAIN="elive-tools"
export TEXTDOMAIN


message_done="$( printf "$( eval_gettext "All operations are finished. You can now close the terminal." )" "" )"

not_supported(){
    local mime file

    mime="$1"
    shift
    file="$1"
    shift

    el_warning "mimetype '$mime' not implemented for '$file'\nls -la: $(ls -la "$file" )\nfile --mime-type: $(file --mime-type "$file")"
}

run_dmg(){
    local message_dmg
    message_dmg="$( printf "$( eval_gettext "DMG files belong to MacOS systems. You cannot create or modify them in Linux, but you can open them to view or extract their content. Do you want to open it now?" )" "" )"

    if $guitool --question --text="$message_dmg" ; then
        filename="$( basename "$file" )"

        if ! el_dependencies_check "7z" ; then
            el_dependencies_install "p7zip-full"
        fi

        mkdir "$(basename $file).EXTRACTED"
        cd "$(basename $file).EXTRACTED"

        7z x "../$( basename "${file}" )"
        # open thunar/fm in actual director
        xdg-open "$(pwd)"
    fi
}

run_e16(){
    local mode
    mode="$1"
    shift
    file="$1"
    shift

    case "$mode" in
        theme)
            if [[ -z "$EROOT" ]] ; then
                $guitool --error --text="$( eval_gettext "This is an Enlightenment 16 theme, login into this window manager in order to be able to use this file." )"
                return
            fi
            mkdir -p "$HOME/.e16/themes"
            cp -f "$file" "$HOME/.e16/themes/"
            # full path is needed for home themes
            eesh theme use "$HOME/.e16/themes/$( basename "$file" )"
            ;;
    esac
}

run_edc_compile(){
    local file file_output
    file="$1"
    shift

    cd "$(dirname "$file" )"
    if [[ -s "build.sh" ]] && grep -qsi "edje_cc" build.sh ; then
        if ! bash build.sh ; then
            logs="$( bash build.sh 2>&1 )"
            $guitool --error --text="$logs" 2>/dev/null
            return 1
        fi
    else
        el_debug "edje_cc -beta '$file'"
        if ! edje_cc -beta "$file" ; then
            logs="$( edje_cc -beta "$file" 2>&1 )"

            local message_error
            message_error="$( printf "$( eval_gettext "This EDC file doesn't compile by itself, search the build.sh file to compile it or use manually the correct edje_cc command" )" "" )"

            el_error "Unable to compile EDC '$file' , result:\n$logs"
            $guitool --warning --text="${message_error}\n\n${logs}" 2>/dev/null

            return 1
        fi
    fi

    file_output="$( find . -type f -iname '*.edj' -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -f2- -d" " )"
    if [[ -s "$file_output" ]] ; then
        run_edje "$file_output"
    fi
}

run_edje(){
    local file groups group_name
    file="$1"
    shift

    while read -ru 3 line
    do
        # note: groups are always listed between ' ' so include them that way and with the wildcard
        [[ "$line" = *"'e/theme/about'"* ]] && is_e_theme=1
        [[ "$line" = *"'e/modules/ibox/"* ]] && is_e_theme=1
        [[ "$line" = *"'elive-gadget-clock"* ]] && is_elive_gadget_clock=1
        [[ "$line" = *"'e/desktop/background'"* ]] && is_e_wallpaper=1
        [[ "$line" = "^0 groups in file"* ]] && is_e_invalid=1
        # generic edjes have 'main'
        [[ "$line" = *"'main'"* ]] && is_main=1

    done 3<<< "$( LC_ALL="$EL_LC_EN" edje_player -G "$file" )"

    # uncompatible edje file
    if ((is_e_invalid)) ; then
        $guitool --error --text="$( eval_gettext "This EDJE file doesn't look to be compatible or we don't know its usage, so we didn't found any group on it. Make sure that is compatible and correctly programmed." )"
        return 0
    fi

    groups="$( LC_ALL="$EL_LC_EN" edje_player -G "$file" | head -1 | awk '{print $1}' )"

    # only wallpaper
    if ((is_e_wallpaper)) && ! ((is_e_theme)) ; then
        # show a preview
        $precmd edje_player "$file"

        if el_user_desktop_running enlightenment ; then
            if $guitool --question --text="$( eval_gettext "Do you want to install this wallpaper?" )" ; then
                $precmd enlightenment_remote -desktop-bg-add-set "$file"
            fi
        fi

        return 0
    fi

    # full E theme
    if ((is_e_theme)) ; then
        if el_user_desktop_running enlightenment ; then
            if $guitool --question --text="$( eval_gettext "Do you want to install this theme?" )" ; then
                $precmd cp -f "$file" "$E_HOME_DIR/themes/"
                # update: seems like it doesn't works?
                enlightenment_remote -theme-set "$E_HOME_DIR/themes/$( basename "$file" )"
                # $guitool --info --text="$( eval_gettext "You can now activate the new theme from the preferences menu. Note that themes may not always be fully compatible; we suggest using the Elive theme for compatibility, stability, and also have the most features." )"
            fi
        else
            $guitool --error --text="$( eval_gettext "This theme requires to have running a newer version of Enlightenment, please login into this window manager in order to be able to use this file." )"
        fi

        return 0
    fi

    # elive gadget clock
    if ((is_elive_gadget_clock)) ; then
        killall elive-gadget-clock || true
        # this runs the clock, adds the theme, and saves it
        elive-gadget-clock --theme "$file"

        return 0
    fi

    # generic edje playable
    if ((is_main)) ; then
        $precmd edje_player --group=main "$file"
        return 0
    fi



    # just play a single group
    if [[ "$groups" = 1 ]] ; then
        # select the (single) group to run:
        # group_name="$( LC_ALL="$EL_LC_EN" edje_player -G "$file" | head -2 | tail -1 )"
        # read -r group_name <<< "$group_name"
        # group_name="${group_name//\'/}"
        # $precmd edje_player -g "$group_name" "$file"

        # by default it runs correctly
        $precmd edje_player "$file"
        return 0
    fi

    # still here? implement it
    $guitool --warning --text="$( eval_gettext "You are trying to run an EDJE file, but we don't know how to use it. Please tell us about this type of file in the Elive forums so we can implement it." )"

    el_warning "Unknown EDJE purpose file: groups:\n$( edje_player -G "$file" )"

    # fallback playing
    $precmd edje_player "$file" || true
}

run_compiler(){
    local file mode

    mode="$1"
    shift
    file="$1"
    shift


    # PKGBUILD files
    if echo "$file" | grep -qs ".*PKGBUILD$" ; then

        if $guitool --question --cancel-label="$( eval_gettext "No" )" --ok-label="$( eval_gettext "Yes" )" --text="$( eval_gettext "PKGBUILD files are meant to build a package, proceed?" )" ; then

            # deps
            if ! el_dependencies_check "makedeb" 2>/dev/null ; then
                $precmd gksu urxvt -e bash -c "source /usr/lib/elive-tools/functions ;
                set +e
                export MAKEDEB_RELEASE=makedeb
                curl -Ls 'https://shlink.makedeb.org/install' | sed -e 's|^.*die.*not allowed.*root user.*$|true|g' > /tmp/.${USER}-script.sh
                chmod +x /tmp/.${USER}-script.sh
                /tmp/.${USER}-script.sh
                rm -f /tmp/.${USER}-script.sh
                sleep 2
                "

                #"$(wget -qO - 'https://shlink.makedeb.org/install')"
            fi


            local message_failed
            message_failed="$( printf "$( eval_gettext "FAILED: If the build failed because of a missing dependency, install it first. Note that more compatible PKGBUILDs are available at mpr.makedeb.org. You can also manually edit the PKGBUILD file to add or remove dependencies as needed." )" "" )"


            # build
            $precmd urxvt -e bash -c "source /usr/lib/elive-tools/functions ;
                if makedeb -s \"$file\" ; then
                    is_build=1
                else
                    echo -e '\nPossible packages to satisfy dependencies:'
                    source \"$file\"
                    for package in \"\${depends[@]}\" ; do
                        apt-cache search glew | awk '{print \$1}' | sort | psort -- -p \"^\${package}\$\" -p \"^lib\" -p \"\-dev\$\" | head -5 | tr '\n' ' ' ; echo
                    done

                    printf \"\n%s\n\" \"$message_failed\"
                    echo ; grep -H '^depends=' \"$file\"
                    #if el_confirm '\nTry again ignoring defined dependencies?' ; then
                        if makedeb -d --no-check \"$file\" ; then
                            is_build=1
                        else
                            echo ; echo -e 'FAILED - review why it failed and close the terminal when finish' ; sleep 20m
                        fi
                    #fi
                fi
                if ((is_build)) ; then
                    el_notify normal logo-elive 'Package build' 'Package is built. You can install it now with double-click the file.'
                fi
                "
        fi

        # if ((is_root_wanted)) ; then
        #     gksu "$file" ${options_appimage}
        # else
        #     "$file" ${options_appimage}
        # fi
        #

    fi

    if [[ "$mime" = "text/x-makefile" ]] ; then
        $precmd urxvt -hold -e bash -c "make && echo -e \"\n\nCOMPILED\n\""
    fi
}


run_script(){
    local file mode

    mode="$1"
    shift
    file="$1"
    shift


    # window executables?
    if echo "$file" | grep -qsi ".*\.exe" ; then
        # in fact im not sure that "application/x-executable" is a mimemtype for windows files, but just in case:
        # if wine was not installed, run it twice so first it will install the real one:
        if [[ -e "/var/lib/dpkg/info/pulseaudio.list" ]] ; then
            wine start /unix "$file"
        fi

        # run wine
        wine start /unix "$file"

        exit
    fi

    # warn user
    if ! $guitool --question --text="$( eval_gettext "You are about to execute a file. Since it can run arbitrary code on your machine, it is crucial to know it comes from a well-known author or trusted source. Continue?" )" ; then
        return 0
    fi

    #el_config_get "is_user_warned_root"
    #if ! ((is_user_warned_root)) ; then
        #$guitool --info --text="$( eval_gettext "Important: sometimes these scripts needs administrator privileges, if this is the case you need to right-click in the filemanager to enter in admin mode, then run the file from this new session." )"
        #is_user_warned_root=1
        #el_config_save "conf_is_user_warned_root"
    #fi

    if ! [[ "$UID" = 0 ]] ; then
        if $guitool --question --cancel-label="$( eval_gettext "No" )" --ok-label="$( eval_gettext "Yes" )" --text="$( eval_gettext "Do you need administrator privileges to run this file? This is often required if you are attempting to install software or a driver on your system. We recommend first trying to run the file without administrator privileges." )" ; then
            is_root_wanted=1
        fi
    fi

    if ! test -x "$file" ; then
        #if $guitool --question --text="$( eval_gettext "Add executable permissions to the file?" )" ; then
            $precmd chmod +x "$file"
        #else
            #$guitool --error --text="$( eval_gettext "If the file has doesn't have executable permissions we cannot run it. Exiting..." )"
            #return 1
        #fi
    fi



    # nvidia installer?
    if echo "$file" | grep -qsi "NVIDIA.*\.run$" ; then
        if $guitool --question --text="$( eval_gettext "Elive offers a better, cleaner Nvidia driver installer. Would you prefer to use this instead of the official Nvidia installer?" )" ; then
            if [[ -x "$( which urxvt )" ]] ; then
                $precmd gksu urxvt -e bash -c '/usr/sbin/nvidia-privative-drivers-install'
            else
                el_error "no urxvt found"
            fi

            #all done
            exit
        fi
    fi

    # AppImage files
    if echo "$file" | grep -qsi ".*\.AppImage$" ; then

        if ! $guitool --question --cancel-label="$( eval_gettext "No" )" --ok-label="$( eval_gettext "Yes" )" --text="$( eval_gettext "Run this AppImage it in sandbox mode? Strongly suggested for security reasons unless you need to run it under your own system" )" ; then
            options_appimage="--no-sandbox ${options_appimage}"
        fi
        local message_appimage_important
        message_appimage_important="$( printf "$( eval_gettext "Important: The next time you double-click the .AppImage file, it will automatically run from your user. If you wish to run it again with specific options, right-click and select: 'Open with -> Elive Run Helper'." )" "" )"

        # not needed, will popup later
        #$guitool --info --text="$message_appimage_important"

        if ((is_root_wanted)) ; then
            gksu "$file" ${options_appimage}
        else
            "$file" ${options_appimage}
        fi

        el_notify normal logo-elive "Remember" "$message_appimage_important"

        exit
    fi



    if [[ "$UID" = 0 ]] ; then
        # root run from a terminal
        $precmd urxvt -hold -e bash -c "$file ; apt-get -f install ; echo ; echo ; echo ${message_done}"
    else
        # user mode
        if [[ -s "/etc/sudoers.d/sudo_nopasswd_packagers_$USER" ]] ; then
            # auto sudo
            if ((is_root_wanted)) ; then
                $precmd gksu urxvt -hold -e bash -c "$file ; apt-get -f install ; echo ; echo ; echo ${message_done}"
            else
                $precmd urxvt -hold -e bash -c "$file ; source /usr/lib/elive-tools/functions ; el_sudo apt-get -f install ; echo ; echo ; echo ${message_done}"
            fi
        else
            # no sudo
            if ((is_root_wanted)) ; then
                $precmd urxvt -hold -e bash -c "gksu $file ; echo ; echo ; echo ${message_done}"
            else
                $precmd urxvt -hold -e bash -c "$file ; echo ; echo ; echo ${message_done}"
            fi
        fi
    fi
}


main(){
    # pre {{{
    local file

    # include simulate mode
    if [[ "$1" = "-s" ]] || [[ "$1" = "--simulate" ]] ; then
        is_simulate=1
        precmd="echo"
        shift
    fi

    # just make sure we have urxvt installed and don't waste code
    if ! el_dependencies_check "urxvt" ; then
        el_dependencies_install "rxvt-unicode"
    fi

    if [ -n "$E_START" ] && [ -z "$E_HOME_DIR" ] ; then
        E_HOME_DIR="$HOME/.e/e17"
    fi

    # }}}

    for file in "$@"
    do
        file="$( LC_ALL="$EL_LC_EN" readlink -f "$file" )"
        [[ ! -e "$file" ]] && continue

        dirname="$( dirname "$file" )"

        mime="$( LC_ALL="$EL_LC_EN" file -bi "$file" | sed -e 's|; charset.*$||g' )"
        [[ -z "$mime" ]] && continue

        el_debug "MIME: $mime"

        [[ "$mime" = "inode/x-empty" ]] && continue

        # some fixes
        # XXX IMPORTANT: file --mime-type doesn't always include all the values, check in thunar properties "what name says the file type has" and then search it in the mimetype freedesktop database in /usr/share/mime/packages/freedesktop.org.xml
        case "$mime" in
            "application/gzip"|"application/zip"|"application/x-e-theme")
                if echo "$file" | grep -qsi "\.etheme" ; then
                    mime="application/x-e-theme"
                fi

                ;;
            "text/plain"|"application/octet-stream")
                unset mime

                # PKGBUILD
                if echo "$( basename "$file" )" | grep -qs "^PKGBUILD$" ; then
                    mime="text/PKGBUILD"
                fi

                # flatpak
                if echo "$( basename "$file" )" | grep -qsi "\.flatpakref$" ; then
                    # install dep
                    if ! el_dependencies_check "flatpak" ; then
                        el_dependencies_install "flatpak|gnome-software-plugin-flatpak"
                    fi
                fi

                # edje files are octets
                if echo "$( basename "$file" )" | grep -qsi "\.edj$" ; then
                    if edje_player -G "$file" | head -5 | grep -qs "group.*in file" ; then
                        mime="application/edje"
                    fi
                fi
                # edc files are text/plain
                if echo "$( basename "$file" )" | grep -qsi "\.edc$" ; then
                    mime="text/edje"
                fi

                # script files
                if [[ -z "$mime" ]] ; then
                    if head -1 "$file" | grep -qsE "^#!.*(bin/env |bin/)(bash|sh|dash|zsh)$" ; then
                        mime="text/x-shellscript"
                    fi
                fi
                if [[ -z "$mime" ]] ; then
                if echo "$( basename "$file" )" | grep -qsi "\.run$" ; then
                        mime="text/x-shellscript"
                    fi
                fi
                if [[ -z "$mime" ]] ; then
                    if LC_ALL="$EL_LC_EN" file "$file" | grep -qsi "script.*text.*executable" ; then
                        mime="text/x-shellscript"
                    fi
                fi

                if [[ -z "$mime" ]] ; then
                    mime="text/plain"
                fi
                ;;
        esac

        # do not run empty mimes
        if [[ -z "$mime" ]] ; then
            $guitool --info --text="$( eval_gettext "This file doesn't have a Mimetype assigned, we cannot run or open something if we don't know how it should be run. This file is probably used for other purposes." )"
            exit
        fi

        # always do things from the dir itself
        cd "$dirname"

        # parse and run
        case "$mime" in
            "text/x-shellscript"|"application/x-executable")
                run_script "user" "$file"
                ;;
            "text/x-ruby"|"text/x-perl"|"text/x-awk"|"text/x-python")
                run_script "user" "$file"
                ;;
            "text/PKGBUILD")
                run_compiler "user" "$file"
                exit
                ;;
            "text/plain")
                if [[ -x "$( which scite )" ]] ; then
                    scite "$file"
                    exit
                fi
                ;;
            "application/zlib"|"application/x-bzip2")
                if echo "$file" | grep -qsi "\.dmg$" ; then
                    run_dmg "user" "$file"
                fi
                ;;
            "text/x-makefile")
                run_compiler "user" "$file"
                exit
                ;;
            "text/edje")
                run_edc_compile "$file"
                ;;
            "application/edje"|"application/x-extension-edj")
                run_edje "$file"
                ;;
            "application/x-e16-theme"|"application/x-e-theme")
                run_e16 "theme" "$file"
                ;;
            "application/x-iso9660-image")
                $guitool --info --text="$( eval_gettext "This is an ISO image file; you can burn it to a DVD or a USB device. Elive includes its own tool to record USBs correctly. You can also mount it and view its contents by right-clicking the file." )"
                ;;
            "regular file, no read permission")
                $guitool --error --text="$( eval_gettext "You don't have read permission for this file. To read it, open your file manager in Admin mode by right-clicking its directory, then change the file's read permissions." )"
                ;;
            *)
                # already supported by default list (they just works using thunar), tested with starting by application/
                if ! echo "$mime" | grep -qsE "(/.*debian.*package$|inode/directory)" ; then
                    not_supported "$mime" "$file"
                    exit
                fi
                # run a default launcher in any of the cases!
                if [[ -x "/usr/bin/thunar" ]] ; then
                    #$precmd xdg-open "$file"  # do not use this option, it ends in a loop
                    el_debug "fallback to open file directory"
                    thunar "$( dirname "$file" )"
                    exit
                fi
                ;;
        esac
    done
}

#
#  MAIN
#
main "$@"

# vim: set foldmethod=marker :
