#!/bin/sh

set -e

# Check if command is available
has() {
    command -v "$1" >/dev/null 2>&1
}

is_under_termux() {
    has termux-setup-storage
}

contains() {
    string="$1"
    substring="$2"
    if test "${string#*$substring}" != "$string"
    then
        return 0
    else
        return 1
    fi
}

install_completions() {
    test "$OS" = "Darwin" && return 0

    COMPLETIONS="$1"

    if has zsh;
    then
        info "Installing zsh completions"
        TARGET="/usr/share/zsh/vendor-completions"
        sudo mkdir -p "$TARGET"
        sudo cp "$COMPLETIONS/mangal.zsh" "$TARGET/_mangal"
    fi

    if has fish;
    then
        info "Installing fish completions"
        TARGET="/usr/share/fish/completions"
        sudo mkdir -p "$TARGET"
        sudo cp "$COMPLETIONS/mangal.fish" "$TARGET/mangal.fish"
    fi

    if has bash;
    then
        info "Installing bash completions"
        TARGET="/usr/share/bash-completion/completions"

        sudo mkdir -p $TARGET
        sudo cp "$COMPLETIONS/mangal.bash" "$TARGET/mangal"
    fi
}

info() {
    printf "\033[1;35m%s\033[0m %s\n" "info:" "$1"
}

warn() {
    printf "\033[1;33m%s\033[0m %s\n" "warning:" "$1"
}

err() {
    printf "\033[1;31m%s\033[0m %s\n" "error:" "$1" >&2
}

die() {
    err "$1"
    exit 1
}

# Download file. first argument is out path, second is URL
download() {
    if has curl; then
        curl -sfLo "$1" "$2"
    elif has wget; then
        wget -qO "$1" "$2"
    else
        die "No download program (curl, wget) found, please install one."
    fi
}

verify_checksums() {
    info "Verifying checksums"
    if has sha256sum; then
        OK=$(sha256sum --ignore-missing --quiet --check checksums.txt)
    else
        OK=$(shasum -a 256 --ignore-missing --quiet --check checksums.txt)
    fi

    $OK || die "Checksums did not match! Abort"
}

install_deb() {
    if ! has dpkg; then
        warn "dpkg is not available. Using alternative method"
        install_binary
        return
    fi

    case "$ARCH" in
    aarch64)
        ARCH="arm64"
        ;;
    armv*)
        ARCH="armhf"
        ;;
    x86_64)
        ARCH="amd64"
        ;;
    i*)
        ARCH="i386"
        ;;
    esac

    DEB_NAME="${FILE_BASENAME}_${VERSION}_${ARCH}.deb"
    DEB_FILE="$TMPDIR/$DEB_NAME"

    export DEB_FILE DEB_NAME

    (
        cd "$TMPDIR"

        info "Downloading $DEB_NAME"
        download "$DEB_FILE" "$RELEASES_URL/download/$TAG/$DEB_NAME"

        info "Downloading checksums"
        download "checksums.txt" "$RELEASES_URL/download/$TAG/checksums.txt"

        verify_checksums
    )

    info "Installing"
    sudo dpkg --install "$DEB_FILE"
}

install_termux() {
    info "Installing for Termux"
    pkg install mangal
}

install_macos() {
    if ! has brew; then
        warn "Homebrew is not installed. Using alternative method"
        install_binary
        return
    fi

    info "Installing with Homebrew"
    brew tap metafates/mangal

    if has mangal; then
        brew reinstall mangal
    else
        brew install mangal
    fi
}

install_rpm() {
    if ! has rpm; then
        warn "rpm is not available. Using alternative method"
        install_binary
        return
    fi

    case "$ARCH" in
    arm64)
        ARCH="aarch64"
        ;;
    armv*)
        ARCH="armv6hl"
        ;;
    amd64)
        ARCH="x86_64"
        ;;
    i*)
        ARCH="i386"
        ;;
    esac

    RPM_NAME="${FILE_BASENAME}-${VERSION}.${ARCH}.rpm"
    RPM_FILE="$TMPDIR/$DEB_NAME"

    export RPM_FILE RPM_NAME

    (
        cd "$TMPDIR"

        info "Downloading $RPM_NAME"
        download "$DEB_FILE" "$RELEASES_URL/download/$TAG/$RPM_NAME"

        info "Downloading checksums"
        download "checksums.txt" "$RELEASES_URL/download/$TAG/checksums.txt"

        verify_checksums
    )

    info "Installing"
    sudo rpm --install "$RPM_FILE"
}

install_binary() {
    info "Installing raw binary"

    case "$ARCH" in
    aarch64)
        ARCH="arm64"
        ;;
    armv*)
        ARCH="armv6"
        ;;
    amd64)
        ARCH="x86_64"
        ;;
    i*)
        ARCH="i386"
        ;;
    esac

    TAR_NAME="${FILE_BASENAME}_${VERSION}_${OS}_${ARCH}.tar.gz"
    TAR_FILE="$TMPDIR/$TAR_NAME"

    export TAR_NAME TAR_FILE

    (
        cd "$TMPDIR"

        info "Downloading $TAR_NAME"
        download "$TAR_FILE" "$RELEASES_URL/download/$TAG/$TAR_NAME"

        info "Downloading checksums"
        download "checksums.txt" "$RELEASES_URL/download/$TAG/checksums.txt"

        verify_checksums
    )

    tar -xf "$TAR_FILE" -C "$TMPDIR"

    if [ -d "/usr/local/bin/" ];
    then
        OUT="/usr/local/bin/"
    else
        OUT="/usr/bin/"
    fi

    info "Moving to ${OUT}"
    sudo sh -c "install -Dm755 '$TMPDIR/$FILE_BASENAME' '${OUT}'"
    install_completions "$TMPDIR/completions"
}

pre_install() {
    has mangal && warn "mangal is installed already, reinstalling"

    RELEASES_URL="https://github.com/metafates/mangal/releases"
    FILE_BASENAME="mangal"

    info "Fetching latest version"
    TAG="$(curl -sfL -o /dev/null -w "%{url_effective}" "$RELEASES_URL/latest" |
        rev |
        cut -f1 -d'/' |
        rev)"

    test -z "$TAG" && {
        die "Unable to get mangal version."
    }

    OS=$(uname -s)
    ARCH=$(uname -m)
    VERSION=${TAG#?}

    info "Latest version is $VERSION"

    TMPDIR="$(mktemp -d)"
}

post_install() {
    if has mangal; then
        printf "\n🎉 \033[1;32mMangal was installed successfully\033[0m\n\n"
    else
        die "Mangal was not installed or it's not in the PATH."
    fi
}

install() {
    pre_install

    case $OS in
    Darwin)
        info "macOS detected"
        install_macos
        ;;
    Linux)
        case $(cat /etc/*release 2>/dev/null | tr "[:upper:]" "[:lower:]") in
        *ubuntu*)
            info "Ubuntu detected"
            install_deb
            ;;
        *debian*)
            info "Debian detected"
            install_deb
            ;;
        *fedora*)
            info "Fedora detected"
            install_rpm
            ;;
        *)
            if is_under_termux; then
                info "Termux detected"
                install_termux
            else
                info "Linux detected"
                install_binary
            fi
            ;;
        esac
        ;;
    *)
        err "Unknown OS detected: $OS"
        ;;
    esac

    post_install
}

install
