#!/bin/sh

##########################################################################
#   Script description:
#       Manage software packages
#       
#   History:
#   Date        Name        Modification
#   2020-12-27  J Bacon     Begin
##########################################################################

usage()
{
    printf "Usage: $0\n"
    exit 1
}


##########################################################################
#   Function description:
#       Pause until user presses return
##########################################################################

pause()
{
    local junk
    
    printf "Press return to continue..."
    read junk
}


##########################################################################
#   Main
##########################################################################

if [ $# != 0 ]; then
    usage
fi

case $(auto-ostype) in
DragonFly|FreeBSD)
    installed_cmd='pkg info'
    available_cmd='pkg search ".*"'
    search_cmd='pkg search'
    install_cmd='pkg install -y'
    auto_install_packages='auto-install-packages -n -s'
    install_from_source_cmd="$auto_install_packages"
    remove_cmd='pkg remove -y'
    autoremove_cmd='pkg autoremove -y'
    ;;

Darwin|NetBSD|RHEL)
    if [ -e $(auto-pkgsrc-prefix)/bin/pkgin ]; then
	installed_cmd='pkgin list'
	available_cmd='pkgin avail'
	search_cmd='pkgin search'
	install_cmd='pkgin -y install'
	remove_cmd='pkgin -y remove'
	autoremove_cmd='pkgin -y autoremove'
    else
	installed_cmd='pkg_info'
	available_cmd="find $(auto-pkgsrc-dir) -mindepth 3 -maxdepth 3 -name Makefile | awk -F '/' '\$0 !~ \"/wip/\" { printf(\"%s/%s\n\", \$(NF-2), \$(NF-1)); }'"
	search_cmd="find $(auto-pkgsrc-dir) -mindepth 2 -maxdepth 2 | grep -E"
	install_cmd='no-pkgin'
	remove_cmd='pkg_delete'
	autoremove_cmd='no-autoremove'
    fi
    
    # FIXME: Add pkgsrc support to auto-install-packages
    # install_from_source_cmd='auto-install-packages -n -s'
    ;;

*)
    auto-unsupported-os $0
    exit 1
    ;;

esac

while true
do
    clear
    auto-admin-banner
    cat << EOM

To see ports by category, run "ls /usr/ports" and e.g. "ls /usr/ports/audio"
or browse the collection at https://www.freebsd.org/ports/index.html.

1.. List installed packages
2.. List available packages
3.. Search available packages
4.. Install packages
5.. Remove packages
6.. Install port/package from source
7.. Tag a port/package for installation from source
8.. Tag a binary package as critical
9.. Upgrade all pkgsrc packages
10. Switch from quarterly to latest packages
11. Upgrade the base system
Q.. Quit

EOM

    printf "Selection? "
    read resp
    case $resp in
    1)
	$installed_cmd | more
	printf "$($installed_cmd | wc -l) packages installed.\n"
	pause
	;;

    2)
	tmpfile=.auto-software-manager-packages.txt
	eval $available_cmd > $tmpfile
	more $tmpfile
	printf "$(cat $tmpfile | wc -l) packages available.\n"
	rm -f $tmpfile
	pause
	;;

    3)
	printf "Enter any part of the package name: "
	read pattern
	eval $search_cmd "$pattern" | more
	pause
	;;
    
    4)
	if [ "$install_cmd" = 'no-pkgin' ]; then
	    printf "No pkgin command for this tree.  Use install from source.\n"
	    pause
	else
	    printf "Enter the package name(s): "
	    read names
	    if [ 0"$names" != 0 ]; then
		$install_cmd $names
		pause
	    fi
	fi
	;;
    
    5)
	printf "Enter the package name(s): "
	read names
	if [ 0"$names" != 0 ]; then
	    printf "Automatically remove unneeded dependencies? [y]/n "
	    read deps
	    if [ "$remove_cmd" = pkg_delete ]; then
		$remove_flags='-rR'
	    fi
	    $remove_cmd $remove_flags $names
	    if [ 0"$deps" != 0n ] && [ "$autoremove_cmd" != 'no-autoremove' ]; then
		$autoremove_cmd
	    fi
	    pause
	fi
	;;
    
    6)
	printf "Enter category/name: "
	read names
	if [ 0"$names" != 0 ]; then
	    # FIXME: Change when auto-install-packages supports pkgsrc
	    if [ 0"$install_from_source_cmd" = 0"$auto_install_packages" ]; then
		set -x
		$install_from_source_cmd $names
		set +x
	    else
		make=$(auto-pkgsrc-make)
		for name in $names; do
		    cd $(auto-pkgsrc-dir)/$name
		    $make clean clean-depends install
		done
	    fi
	    pause
	fi
	;;

    7)
	if [ "$install_cmd" = 'no-pkgin' ]; then
	    printf "No pkgin command for this tree.  Tagging makes no sense here.\n"
	else
	    cat << EOM

Users may need to install some ports/packages from source even though they use
binary packages for most installs, because some ports/packages cannot be
distributed in binary form for licensing reasons, to build with non-default
options, or to build with non-portable optimizations (e.g. -march=native).

Tagging a port/package for installation from source here will inform
auto-update-system that it should be rebuilt from source following package
upgrade and ports/pkgsrc tree updates.

To avoid compatibility issues, you must ensure that your ports/pkgsrc tree
and installed packages are in sync.  This can be generally be ensured by using
auto-update-system (first option in this menu), which ensures that your
ports/pkgsrc tree and binary package are on the same branch, and updates
them together.

Note that using latest binary packages on some platforms may make it
impossible to keep them in sync, because latest binary packages are not built
regularly.  Hence, the binary package may be far behind the current source
tree.  On FreeBSD and NetBSD amd64, latest packages are built continuously
and generally lag behind ports by no more than a few days.  Hence, mixing on
amd64 is very safe as long as the ports/pkgsrc tree and installed packages
are up-to-date.

EOM
    pause
    cat << EOM

Mixing quarterly ports/pkgsrc and binary packages is generally safe since
versions never change except in very rare cases to resolve serious issues.
Binary packages are generally rebuilt quickly after such updates to ensure
compatibility.

If building with non-default options, you must ensure that the build is
compatible with dependent ports/packages.  (This is an issue whether mixing
source builds and binary packages or building everything from source.)

EOM
	    printf "category/port? "
	    read port
	    if [ 0"$port" != 0 ]; then
		printf "Reason for installing from source? (one word, e.g. license) "
		read reason
		choice=' '
		while [ 0"$choice" != 01 ] && [ 0"$choice" != 2 ]; do
		    cat << EOM

1.. Reinstall only if port is newer than installed version
2.. Always reinstall

EOM
		    read choice
		done
		if [ $choice = 1 ]; then
		    when=newer
		else
		    when=always
		fi
		auto-mark-install-from-source $port $reason $when
		printf "Edit /usr/local/etc/auto-admin/install-from-source to cancel.\n"
	    fi
	fi
	pause
	;;
    
    8)
	if [ "$install_cmd" = 'no-pkgin' ]; then
	    printf "No pkgin command for this tree.  Tagging makes no sense here.\n"
	else
	    cat << EOM

Occasionally an important port becomes broken and running package upgrades
will remove it from your system as a result. This is almost never an issue
with quarterly packages, but is something you will likely experience
eventually if using latest packages.  

Tagging a package as critical informs auto-update-system that you would like
to be notified that this package is missing from the repository before
proceeding with ports and package upgrades.  Generally these issues are fixed
within quickly, so simply holding off on upgrades for a while is the easiest
solution.

Desktop-installer automatically tags certain packages, such as the chosedn
desktop environment or window manager, xorg, etc.

EOM
	    printf "Package name? "
	    read package
	    if [ 0"$package" != 0 ]; then
		auto-mark-package-critical $package || true
	    fi
	fi
	pause
	;;
    
    9)
	if auto-using-pkgsrc; then
	    printf "This will update your pkgsrc tree and all installed packages.\n"
	    printf "Proceed? y/[n] "
	    read proceed
	    if [ 0"$proceed" = 0y ]; then
		auto-update-pkgsrc --defaults
	    fi
	else
	    printf 'Not using pkgsrc.  Use "Update system" in the auto-admin main menu.\n'
	fi
	pause
	;;
	
    10)
	auto-pkg-latest
	pause
	;;
    
    11)
	auto-upgrade-base
	pause
	;;
    
    Q|q)
	exit 0
	;;

    *)
	printf "Invalid option: $resp\n"
    esac
done
