#!/usr/bin/env bash
set -euo pipefail

origin='github.com/bottlesdevs/bottles'
min_cpak_version='2.14.8'

usage() {
    cat <<'USAGE'
Usage: bottles-cpak [run [ARGS...] | install | update | remove | doctor | help]

  run       Install Bottles on first use, then launch it (default)
  install   Install the official Bottles main CPak package for this user
  update    Update the installed Bottles CPak package
  remove    Remove the Bottles CPak installation (retains user data)
  doctor    Check CPak host requirements
  help      Show this help

CPak is managed separately. Obtain CPak 2.14.8 or newer from:
https://cpak.it/docs/install
USAGE
}

if [[ ${1:-} == help || ${1:-} == -h || ${1:-} == --help ]]; then
    usage
    exit 0
fi

if ! command -v cpak >/dev/null 2>&1; then
    printf '%s\n' 'Bottles (CPak) requires CPak 2.14.8 or newer.' \
        'Install the cpak and cpak-storaged binaries using:' \
        'https://cpak.it/docs/install' >&2
    exit 127
fi

version_output="$(cpak --version 2>&1)" || {
    printf '%s\n' 'Unable to determine CPak version. Try: cpak --version' >&2
    exit 1
}
version="$(printf '%s\n' "$version_output" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n 1 || true)"
if [[ -z $version ]]; then
    printf 'Unable to parse CPak version: %s\n' "$version_output" >&2
    exit 1
fi
if [[ $(printf '%s\n' "$min_cpak_version" "$version" | sort -V | head -n 1) != "$min_cpak_version" ]]; then
    printf 'CPak %s is too old; Bottles Office testing requires %s or newer.\n' \
        "$version" "$min_cpak_version" >&2
    exit 1
fi

installed() {
    local inventory
    inventory="$(cpak list --json)" || return 2
    grep -Fq "$origin" <<< "$inventory"
}

install_bottles() {
    local status=0
    installed || status=$?
    if (( status == 0 )); then
        printf '%s\n' 'Bottles is already installed in CPak.' >&2
        return 0
    elif (( status != 1 )); then
        printf '%s\n' 'Unable to check CPak installed packages.' >&2
        return 1
    fi
    printf '%s\n' 'Installing official Bottles (main) through CPak for this user...' >&2
    cpak install -b main "$origin"
}

command="${1:-run}"
if (( $# > 0 )); then shift; fi

case "$command" in
    run)
        install_bottles
        if command -v bottles-office-experimental >/dev/null 2>&1; then
            if ! bottles-office-experimental install; then
                printf '%s\n' 'Microsoft 365 setup did not complete. Opening Bottles normally.' >&2
            fi
        fi
        exec cpak run "$origin" bottles "$@"
        ;;
    install)
        if (( $# > 0 )); then usage >&2; exit 64; fi
        install_bottles
        ;;
    update)
        if (( $# > 0 )); then usage >&2; exit 64; fi
        cpak update "$origin"
        ;;
    remove)
        if (( $# > 0 )); then usage >&2; exit 64; fi
        cpak remove "$origin"
        ;;
    doctor)
        if (( $# > 0 )); then usage >&2; exit 64; fi
        cpak doctor
        ;;
    *)
        usage >&2
        exit 64
        ;;
esac
