#!/bin/bash


usage() {
    local self
    self="$(basename "$0")"
    warn "usage: $self [-f|--force] [+TEMPLATE] FILE"
    warn "usage: $self -l|--list"
    exit 2
}

warn() {
    #
    # Print warning
    #
    echo "$@" >&2
}

die() {
    #
    # Warn and exit prematurely
    #
    warn "$@"
    exit 3
}

lstemplates() {
    #
    # Print list of valid templates
    #
    echo pya
    echo shellfu
    echo Bash
    echo Lua
    echo Perl
    echo py3
    echo Python3
    echo Python
}

#shellcheck disable=SC2016
mktemplate() {
    #
    # Print template $Template for $FilePath
    #
    case "$Template" in
        sh)
            echo "#!/bin/sh"
            echo ''
            echo ''
            ;;
        bash|Bash)
            echo "#!/bin/bash"
            echo ''
            echo ''
            ;;
        lua|Lua)
            echo "#!$(which lua)"
            echo ''
            ;;
        pl|Perl)
            echo "#!$(which perl)"
            echo ''
            echo 'use strict;'
            echo 'use warnings;'
            echo ''
            echo ''
            ;;
        py|Python)
            echo "#!$(which python)"
            echo ''
            echo "if __name__ == '__main__':"
            echo '    '
            ;;
        py3|Python3)
            echo "#!/usr/bin/python3"
            echo ''
            echo "if __name__ == '__main__':"
            echo '    '
            ;;
        pya)
            echo '#!/usr/bin/python'
            echo '"""'
            echo 'A simple application'
            echo '"""'
            echo ''
            echo 'import sys'
            echo ''
            echo ''
            echo 'class App(object):'
            echo '    """'
            echo '    Main application class'
            echo '    """'
            echo ''
            echo '    def __init__(self, argv):'
            echo '        self.argv = argv'
            echo '        # agument decoding and further initializations'
            echo ''
            echo '    @classmethod'
            echo '    def main(cls, argv):'
            echo '        """'
            echo '        Initialize and launch'
            echo '        """'
            echo '        app = cls(argv)'
            echo '        app.run()'
            echo ''
            echo '    def run(self):'
            echo '        """'
            echo '        Run the application'
            echo '        """'
            echo '        # actual action (calling other methods)'
            echo '        print self.argv'
            echo '        print __doc__'
            echo ''
            echo ''
            echo 'if __name__ == '__main__':'
            echo '    App.main(sys.argv)'
            ;;
        shellfu)
            echo "#!/bin/bash"
            echo ""
            echo '#shellcheck disable=SC1090'
            echo '. "$(sfpath)" || exit 3'
            echo ''
            echo 'shellfu import pretty'
            echo ''
            echo 'usage() {'
            echo '    mkusage "$@" "[-d] [-v] ARG..."'
            echo '}'
            echo ''
            echo 'main() {'
            echo '    while true; do case $1 in'
            echo '        -d) PRETTY_DEBUG=true;   shift ;;'
            echo '        -v) PRETTY_VERBOSE=true; shift ;;'
            echo '        -*) usage -w "unknown argument: $1" ;;'
            echo '        *)  break ;;'
            echo '    esac done'
            echo '}'
            echo ''
            echo 'main "$@"'
            ;;
        *)
            die "unknown template or language: $Template"
            ;;
    esac
}

guess_language() {
    #
    # Guess intended language from filepath $FilePath
    #
    local fname     # file name
    fname="$(basename "$FilePath")"
    case "$fname" in
        *.*)    echo "${fname##*.}" ;;
        *)      echo "$MKX_DEFAULT_LANG" ;;
    esac
}


#
# Default language
#
MKX_DEFAULT_LANG=${MKX_DEFAULT_LANG:-sh}

main() {
    local FilePath  # destination file path
    local Template  # built-in template name
    local careful     # ignore existing file
    careful=true
    while true; do case $1 in
        -f|--force) careful=false; shift ;;
        -l|--list)  lstemplates; exit 0 ;;
        -*) usage ;;
        +*) Template="${1:1}"; shift ;;
        *)  break ;;
    esac done
    FilePath="$1"
    test -n "$FilePath" || usage
    test -f "$FilePath" && $careful && die "file already exists: $FilePath"
    test -n "$Template" || Template=$(guess_language)
    mktemplate > "$FilePath"
    chmod +x "$FilePath"
}

main "$@"