#!/usr/bin/env sh

# This script installs the default things for having a stylish zsh
user=$USER
user_shell=`getent passwd $USER | cut -f7 -d:`

info() {
    echo -e '\033[1m'info:'\033[0m' $@
}

info_n() {
    echo -en '\033[1m'info:'\033[0m' $@
}

warn() {
    echo -e '\033[33;1m'warning:'\033[0m' $@
}

warn_n() {
    echo -en '\033[33;1m'warning:'\033[0m' $@
}

error() {
    echo -e '\033[31;1m'error:'\033[0m' $@
}

error_n() {
    echo -en '\033[31;1m'error:'\033[0m' $@
}

echo_green() {
    echo -e '\033[32;1m'$@'\033[0m'
}

test_command() {
    for i in $@; do
        command -v $i > /dev/null 2>&1
        res=$?
        if [ $res -ne 0 ]; then
            return $res
        fi
    done
}

yes_no_ask_required() {
    yes_no_ask $@ "(required)"
    if [ $? -ne 0 ]; then
        error "refused to perform required task, can't continue"
        exit 1
    fi
}

yes_no_ask() {
    info_n $@ "[Y/n]"
    read answer
    if ! [[ "$answer" == "N" ]] && ! [[ "$answer" == "n" ]]; then
        return 0
    else
        return 1
    fi
}

install() {
    test_command apt
    if [ $? -eq 0 ]; then
        sudo apt install -yqq $@
        return
    fi

    test_command pacman
    if [ $? -eq 0 ]; then
        sudo pacman -S $@
        return
    fi

    error "distribution not recognized, can't install $@."
}

remove() {
    test_command apt
    if [ $? -eq 0 ]; then
        sudo apt purge -yqq $1
        sudo apt autoremove -yqq
        return
    fi

    test_command pacman
    if [ $? -eq 0 ]; then
        sudo pacman -Rsn $1
        return
    fi

    error "distribution not recognized, can't remove $1."
}

install_python3() {
    test_command apt
    if [ $? -eq 0 ]; then
        sudo apt install -yqq python3 python3-pip
        return
    fi

    test_command pacman
    if [ $? -eq 0 ]; then
        sudo pacman -S python python-pip
        return
    fi

    error "distribution not recognized, can't install python3."
}

install_python_neovim() {
    test_command pip3
    if [ $? -eq 0 ]; then
        sudo pip3 install neovim
        return
    fi

    test_command pip
    if [ $? -eq 0 ]; then
        sudo pip install neovim
        return
    fi

    error "couldn't find pip, can't install python-neovim."
}

install_neovim() {
    test_command apt
    if [ $? -eq 0 ]; then
        sudo apt install -yqq neovim
        return
    fi

    test_command pacman
    if [ $? -eq 0 ]; then
        sudo pacman -S neovim
        return
    fi

    error "distribution not recognized, can't install neovim."
}

git_clone() {
    info_n "cloning $1..."
    git clone $@ > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo " OK!"
    else
        echo
        error "clone failed!"
    fi
}

clone_dotfiles() {
    if [ ! -d $HOME/.config/dotfiles ]; then

        test_command git
        if [ $? -ne 0 ]; then
            if [ $sudo_available -ne 0 ]; then
                error "git is needed, but you don't have git or sudo"
                return 1
            else
                yes_no_ask_required "you'll need git for this, do you wish to install git?"
                install git
            fi
        fi

        git_clone https://gitea.tforgione.fr/tforgione/dotfiles/ $HOME/.config/dotfiles

        echo "# Checks that the update is done weekly, if its not done, prints a nice message" > $HOME/.config/dotfiles/zsh/extraconfig.zsh
        echo "export UPDATE_CHECK=weekly" >> $HOME/.config/dotfiles/zsh/extraconfig.zsh
        echo "export UPDATE_CHECK_TYPE=sliding" >> $HOME/.config/dotfiles/zsh/extraconfig.zsh

        mkdir -p $HOME/.config/dotfiles/.data

        if [ $sudo_available -ne 0 ]; then
            touch $HOME/.config/dotfiles/.data/noroot
        fi
    fi
}

configure_dotfiles() {
    if [ ! -d $HOME/.config/dotfiles ]; then
        yes_no_ask "do you wish to configure the dotfiles?"
        if [ $? -ne 0 ]; then
            return
        fi

        clone_dotfiles
    fi
}

configure_shell() {
    installed_locally=false

    yes_no_ask "do you wish to install and configure zsh?"
    if [ $? -ne 0 ]; then
        yes_no_ask "you don't want zsh? Ok... but can I at least give you a nice bashrc?"

        if [ $? -ne 0 ]; then
            info "ok :'( I guess I'm not doing anything then"
            return
        fi

        clone_dotfiles
        rm -f $HOME/.bashrc
        ln -s `realpath $HOME/.config/dotfiles/bashrc` `realpath $HOME/.bashrc`

        mkdir -p $HOME/.config/dotfiles/bash
        echo "# Checks that the update is done weekly, if its not done, prints a nice message" > $HOME/.config/dotfiles/bash/extraconfig.bash
        echo "export UPDATE_CHECK=weekly" >> $HOME/.config/dotfiles/bash/extraconfig.bash

        info "bashrc configured successfully"

        return
    fi

    clone_dotfiles

    test_command zsh
    if [ $? -ne 0 ]; then
        if [ $sudo_available -ne 0 ]; then
            warn "zsh is needed, but you don't have zsh or sudo"
            yes_no_ask "do you want me to compile and install zsh locally?"
            if [ $? -ne 0 ]; then
                error "zsh is needed, but you refused to install zsh"
                return 1
            fi
            installed_locally=true
            info "downloading zsh..."
            mkdir tmp
            cd tmp
            curl https://codeload.github.com/zsh-users/zsh/tar.gz/zsh-5.7.1 --output zsh.tar.gz > /dev/null 2>&1
            tar xvf zsh.tar.gz > /dev/null 2>&1
            cd zsh-zsh-5.7.1
            info "building zsh (this may take a while)..."
            ./Util/preconfig > /dev/null 2>&1
            ./configure --prefix ~/.local/share > /dev/null 2>&1
            make > /dev/null 2>&1
            info "installing zsh (this may take a while)..."
            make install > /dev/null 2>&1
            cd ../../
            rm -rf tmp
            info "zsh installed!"

        else
            yes_no_ask_required "this magnificent prompt is based on zsh, do you wish to install zsh?"
            install zsh
        fi
    fi

    mkdir -p $HOME/.config
    if [ ! -d $HOME/.config/ohmyzsh ]; then
        git_clone https://github.com/ohmyzsh/ohmyzsh $HOME/.config/ohmyzsh
    fi

    if [ -f $HOME/.zshrc ]; then
        path1=`realpath $HOME/.zshrc`
        path2=`realpath $HOME/.config/dotfiles/zshrc`
        if [ "$path1" == "$path2" ]; then
            info "it seems that your zshrc is already a good link."
        else
            if `realpath $HOME/.zshrc`; then
                warn "you already have a zshrc, it will be moved to ~/.zshrc.bak"
                mv $HOME/.zshrc $HOME/.zshrc.bak
            fi
            info "linking zshrc"
            ln -s $HOME/.config/dotfiles/zshrc $HOME/.zshrc
        fi
    else
        info "linking zshrc"
        ln -s $HOME/.config/dotfiles/zshrc $HOME/.zshrc
    fi

    if [ "$user_shell" == "/bin/zsh" ]; then
        info "it seems that you already use zsh."
    else
        info "it seems your shell is not zsh..."

        if [ $sudo_available -eq 0 ]; then
            # Sudo is available, run chsh
            yes_no_ask "do you want to change your shell?"
            if [ $? -eq 0 ]; then
                info "changing your shell"
                sudo chsh $user -s /bin/zsh
            else
                info "not doing anything"
            fi
        else
            info "you don't have root, but you can run 'exec zsh' at the end of your bashrc"
            yes_no_ask "do you wish to do that?"
            if [ $? -eq 0 ]; then
                echo >> $HOME/.bashrc
                if [ "$installed_locally" == "true" ]; then
                    echo "exec ~/.local/share/bin/zsh" >> $HOME/.bashrc
                else
                    echo "exec zsh" >> $HOME/.bashrc
                fi
                echo >> $HOME/.bashrc
            else
                info "not doing anything"
            fi
        fi
    fi
}

configure_neovim() {
    test_command nvim
    if [ $? -ne 0 ] && [ $sudo_available -ne 0 ]; then
        warn "you don't have sudo or neovim, skipping neovim configuration"
        return
    fi

    yes_no_ask "do you wish to install and configure neovim?"

    if [ $? -ne 0 ]; then
        info "not installing neovim"
        return
    fi

    clone_dotfiles

    test_command nvim
    if [ $? -ne 0 ]; then
        info "installing neovim"
        install_neovim
    fi

    # Try and install python3 and python-neovim
    test_command python3 pip3
    if [ $? -ne 0 ]; then
        install_python3
    fi

    install_python_neovim

    # Create config files an directories
    mkdir -p $HOME/.config/nvim $HOME/.nvim/backups $HOME/.nvim/swp $HOME/.nvim/undo
    rm -f $HOME/.config/nvim/init.vim
    ln -s $HOME/.config/dotfiles/init.vim $HOME/.config/nvim/init.vim

    # Install vim plug
    curl -fLo $HOME/.local/share/nvim/site/autoload/plug.vim --create-dirs \
        https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

    # Install plugins
    nvim +PlugInstall +qa
}

configure_powerline() {
    yes_no_ask "do you wish to install powerline fonts?"

    if [ $? -ne 0 ]; then
        return
    fi

    info installing powerline fonts
    git_clone https://github.com/powerline/fonts
    cd fonts
    ./install.sh
    cd ..
    rm -rf fonts
}

configure_rust() {
    yes_no_ask "do you wish to install and configure rust?"
    if [ $? -ne 0 ]; then
        return
    fi

    curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path -y
    export PATH=$HOME/.cargo/bin:$PATH

    cargo_update_installed=1
    yes_no_ask "do you wish to install cargo-update? it allows to update package automatically"
    if [ $? -eq 0 ]; then
        cargo_update_installed=0
        cargo install cargo-update
    fi

    yes_no_ask "do you wish to install racer? it enabled rust completion from vim"
    if [ $? -eq 0 ]; then
        rustup toolchain add nightly
        cargo +nightly install racer
        if [ $cargo_update_installed -eq 0 ]; then
            cargo install-update-config -t nightly racer
        fi
    fi
}

configure_node() {
    yes_no_ask "do you wish to install and configure node and npm?"

    if [ $? -ne 0 ]; then
        return
    fi

    install nodejs npm

    mkdir ~/.npmbin
    npm config set prefix ~/.npmbin
    npm install -g npm

    remove npm
}

configure_awesome() {
    yes_no_ask "do you wish to install and configure awesome?"

    if [ $? -ne 0 ]; then
        return
    fi

    install awesome acpi
    git_clone https://gitea.tforgione.fr/tforgione/awesome ~/.config/awesome

    git_clone https://github.com/horst3180/arc-icon-theme --depth 1 && cd arc-icon-theme
    ./autogen.sh --prefix=/usr
    sudo make install
    cd ..
    rm -rf arc-icon-theme
}

main() {
    echo_green "=== WELCOME TO TFORGIONE'S CONFIG INSTALLER ==="

    info "before anything, i need to know if your user can use sudo"
    yes_no_ask "can your user use sudo?"
    sudo_available=$?

    configure_dotfiles
    configure_shell
    configure_neovim
    configure_powerline
    configure_rust
    configure_node
    configure_awesome
}

main < /dev/tty