#!/bin/bash

# Show the changelog of the given EndeavourOS package-name.

echo2() { echo -e "$@" >&2; }
INFO()  { [ $quiet = no ] && echo2 "==> $progname: info: $1"; }
WARN()  { echo2 "==> $progname: warning: $1"; }
DIE()   { echo2 "\n==> $progname: error: $1\n"; Usage 1; }

DefaultsTo() {
    local var="$1"
    local val="$2"
    [ "$var" = "$val" ] && echo " (default)"
}

Usage() {
    cat <<EOF >&2
Usage: $progname [options] package-name(s)
Options:
       --help, -h            This help.
       --github              Uses github for showing the changelog$(DefaultsTo $preferred_site github).
       --gitlab              Uses gitlab for showing the changelog$(DefaultsTo $preferred_site gitlab).
       --parameters          Show supported package names and options.
       --clfile=X, -c=X      Obtain changelog definitions from the given file X.
       --detect-clfile, -d   [No more used].
       --url, -u             Simply print the changelog URL instead of opening it in a browser.
       --quiet               Don't show purely informational messages (but show errors and warnings).
Notes:
       - By default the changelog URL will be opened in a web browser.
EOF
    [ "$1" ] && exit $1
}

DumpPkgnames() {
    declare -p PKG_CHANGELOGS | sed 's|\[|\n\[|g' | grep "^\[" | sed -E 's|^\[([^]]*).*|\1|'
}
DumpOptions() {
    local sopts2=${sopts//:/}
    local lopts2=${lopts//:/}
    printf "%s\n" ${sopts2//?/-& }--${lopts2//,/ --}
}
SourceClFile() {
    if [ "$clfile" ] ; then
        if [ ! -e "$clfile" ] ; then
            if [ ! -e "/etc/changelogs.conf.$clfile" ] ; then
                DIE "given config file '$clfile' not found"
            else
                clfile="/etc/changelogs.conf.$clfile"
                echo "==> found $clfile" >&2
            fi
        fi
        source "$clfile" || DIE "reading $clfile failed"      # get new PKG_CHANGELOGS and REPONAME
        return 0
    fi
    local file files=() otherdef="./assets.conf"
    if [ -e "$otherdef" ] ; then
        # advanced: use additional changelog definitions in file /etc/changelogs.conf.$rname
        rname=$(grep "^local REPONAME=" "$otherdef" | awk '{print $2}' | cut -d'=' -f2 | sed 's|"||g')
        if [ "$rname" ] ; then
            file="${clfile_eos%.*}.$rname"
            [ -e "$file" ] && files+=("$file")
        fi
    fi
    files+=("$clfile_eos")
    for file in "${files[@]}" ; do
        if [ -e "$file" ] ; then
            clfile="$file"
            source "$clfile" || DIE "reading $clfile failed"      # get new PKG_CHANGELOGS and REPONAME
            return 0
        fi
    done
    DIE "changelog definition file $clfile_eos not found"
}
DumpParameters() {
    SourceClFile
    DumpPkgnames
    DumpOptions
}

Parameters() {
    local sopts="c:dhu"
    local lopts="help,github,gitlab,parameters,clfile:,detect-clfile,quiet,url"
    local opts=""

    opts="$(/usr/bin/getopt -o="$sopts" --longoptions "$lopts" --name "$progname" -- "$@")" || Usage 1
    eval set -- "$opts"

    while [ "$1" ] ; do
        case "$1" in
            --detect-clfile | -d) ;;    # no more needed...
            --parameters)         DumpParameters; exit 0 ;;
            --clfile | -c)        clfile="$2"; shift ;;
            --github | --gitlab)  preferred_site=${1:2} ;;
            --url | -u)           return_url=yes ;;
            --quiet)              quiet=yes ;;
            --help | -h)          Usage 0 ;;
            --)                   shift; break ;;
        esac
        shift
    done
    SourceClFile

    [ "$REPONAME" ]             || DIE "variable REPONAME is not set in config file $clfile"
    [ "${#PKG_CHANGELOGS[@]}" ] || DIE "variable PKG_CHANGELOGS is not set in config file $clfile"
    pkgnames=("$@")
}

Changelog() {
    local -r progname=${0##*/}
    local -r progpath=${0}
    local pkgnames=()
    local preferred_site=gitlab                 # github or gitlab
    local clfile=""                             # for option -c; if given, the file contains PKG_CHANGELOGS and REPONAME
    local -r clfile_eos=/etc/changelogs.conf.endeavouros
    local return_url=no                         # no=open URL, yes=return URL
    local quiet=no
    local REPONAME=""                           # name of the package repository
    declare -A PKG_CHANGELOGS=()                # package-names and changelog-urls

    Parameters "$@"

    HandlePkgnames
}

HandlePkgnames() {
    [ "$pkgnames" ] || DIE "please give package-name(s), for example: $progname akm"
    local pkgname
    local changelog_url=""
    local urls_line=""
    local URLS=()
    local tmp=()

    for pkgname in "${pkgnames[@]}" ; do
        changelog_url="${PKG_CHANGELOGS[$pkgname]}"
        if [ -z "$changelog_url" ] ; then
            [ "$quiet" = no ] && DIE "package name '$pkgname' is not supported in $clfile" || exit 1
        fi

        if [ "$REPONAME" = endeavouros ] ; then
            case "$preferred_site" in
                gitlab)
                    if [ "${changelog_url/github.com\/endeavouros-team/}" != "$changelog_url" ] ; then
                        # convert a github link to a corresponding gitlab link
                        local url_github="$changelog_url"
                        changelog_url=$(eos-github2gitlab "$changelog_url")
                        if [ -z "$changelog_url" ] || [ "$changelog_url" = "$url_github" ] ; then
                            DIE "package name '$pkgname' was not found"
                        fi
                    fi
                    ;;
                github | *)
                    ;;
            esac
        fi

        if [ $return_url = yes ] ; then
            [ "$urls_line" ] && urls_line+="|$changelog_url" || urls_line="$changelog_url"
        else
            readarray -t tmp <<< $(echo "${changelog_url//|/$'\n'}")
            URLS+=("${tmp[@]}")
        fi
    done
    if [ "$urls_line" ] ; then
        echo "$urls_line"            # show the URL(s) separated by '|'
    elif [ "$URLS" ] ; then
        OPEN_URLS "${URLS[@]}"       # open the URL(s)
    fi
}

OPEN_URLS() {
    # use mime binding to open the URL(s) with a browser; if needed, fallback to firefox
    local xx
    if [ -x /bin/exo-open ] ; then
        exo-open "$@"
    elif [ -x /bin/kde-open ] ; then
        for xx in "$@" ; do
            kde-open "$xx"
        done
    elif [ -x /bin/xdg-open ] ; then
        for xx in "$@" ; do
            xdg-open "$xx"
        done
    elif [ -x /bin/firefox ] ; then
        setsid firefox "$@"
    fi
}

Changelog "$@"
