#!/bin/bash

ask_yn () {
        echo "$@"
        while true
        do
                read yn
                case $yn in
                        ([Yy]*) return 0 ;;
                        ([Nn]*) return 1 ;;
                        (*) echo "Enter yes or no" ;;
                esac
        done
}

view_contents () {
    case $1 in
        (*.tar.bz2) tar -tjf "$1" ;;
        (*.tar.gz) tar -tzf "$1" ;;
        (*.bz2) printf "%s\n" "${1%.bz2}" ;;
        (*.rar) unrar l "$1" ;;
        (*.gz) printf "%s\n" "${1%.gz}" ;;
        (*.tar) tar -tf "$1" ;;
        (*.tbz2) tar -tjf "$1" ;;
        (*.tgz) tar -tzf "$1" ;;
        (*.zip) unzip -l "$1" ;;
        (*.Z) printf "%s\n" "${1%.Z}" ;;
        (*.7z) 7z l "$1" ;;
        (*.tar.xz) xz -d "$1" -c | tar -tf - ;;
        (*.xz) printf "%s\n" "${1%.xz}" ;;
        # (*.tar.zst) TODO ;;
        # (*.zst) TODO ;;
        (*.rpm) rpm -qpl "$1" ;;
        (*.jar) jar -tf "$1" ;;
        (*) echo ">>> '$1' cannot be extracted via $0"; exit 1 ;;
    esac
}

extract_archive () {
    case $1 in
            (*.tar.bz2) tar -xjf "$1" ;;
            (*.tar.gz) tar -xzf "$1" ;;
            (*.bz2) bunzip2 "$1" ;;
            (*.rar) unrar x "$1" ;;
            (*.gz) gunzip "$1" ;;
            (*.tar) tar -xf "$1" ;;
            (*.tbz2) tar -xjf "$1" ;;
            (*.tgz) tar -xzf "$1" ;;
            (*.zip) unzip -q "$1" ;;
            (*.Z) uncompress "$1" ;;
            (*.7z) 7z x "$1" ;;
            (*.tar.xz) xz -d "$1" -c | tar -xf - ;;
            (*.xz) xz -d "$1" ;;
            (*.tar.zst) unzstd "$1" -c | tar -xf - ;;
            (*.zst) unzstd "$1" ;;
            (*.rpm) rpm2cpio "$1" | cpio -id --no-absolute-filenames ;;
            (*.jar) jar -xf "$1" ;;
            (*) echo ">>> '$1' cannot be extracted via $0"; exit 1 ;;
    esac
}

assume_yes=true
if [[ $1 == -a ]]; then
    shift
    assume_yes=false
fi

if [[ ! -f $1 ]]; then
    echo ">>> '$1' is not a valid file"
    exit 1
fi

if ! $assume_yes; then
    echo ">>> Getting a list of files in '$1'"
    view_contents "$1" | sort | less
    if ! ask_yn ">>> Extract that file into the current directory?"; then
        exit 0
    fi
fi
extract_archive "$1"

