#!/usr/bin/env bash

{
# saftey/cleanup
# if trap exists
if [ -n "$(command -v "trap")" ]
then
    trap 'unset repo; unset branch; unset setup_or_copy; unset mixin_remote_name; return; exit 0' INT TERM
fi


# 
# make sure xcode tools are installed on MacOS
# 
if [ "$(uname)" = "Darwin" ]
then
    # if non-interactive, then install without prompting
    if [ -z "$PS1" ]; then
        xcode-select -p &> /dev/null
        if [ $? -ne 0 ]; then
            echo "Command Line Tools for Xcode not found. Installing from softwareupdate…"
            # This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
            echo 
            echo "This is probably going to take 5-30min to install" 
            touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress;
            PROD=$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')
            softwareupdate -i "$PROD" --verbose;
        else
            echo "Command Line Tools for Xcode have been installed."
        fi
    # use prompt so the user sees a time estimate and progress
    else
        check=$((xcode-\select --install) 2>&1)
        echo $check
        str="xcode-select: note: install requested for command line developer tools"
        while [[ "$check" == "$str" ]];
        do
           xcode-select --install
           echo "waiting for xcode command line tools to be installed"
           sleep 10
        done
    fi
    echo "passed xcode tools installed"
fi

# TODO: add a check/option for a corrupted nix install

if ! [ -d "/nix/store" ]
then
    echo "|------------------------------------------------------|" 1>&2
    echo "|                                                      |" 1>&2
    echo "|    I'll try to install nix for you                   |" 1>&2
    echo "|    (since I don't see nix yet)                       |" 1>&2
    echo "|                                                      |" 1>&2
    echo "|------------------------------------------------------|" 1>&2
    echo ""
    # check for root
    if [ "$(whoami)" = "root" ]
    then
        echo "$light_yellow"
        echo "looks like you're logged in as root"
        echo "sadly nix can't install on the root user"
        echo "please use a regular user, then re-run this script"
        echo "$color_reset"
        # if users exists
        if [ -n "$(command -v "getent")" ] && [ -n "$(command -v "cut")" ]
        then
            users="$(getent passwd {1000..6000} | cut -d: -f1)"
            if [ -n "$users" ] && [ "$users" != "root" ]
            then
                echo "the available users are:"
                echo "$users"
                echo 
                echo "you should be able to run ${cyan}su ${light_yellow}USER_NAME${color_reset}"
                echo "to login as one of those users"
            else
                echo ""
                echo "it looks like this system doesn't have any regular users"

                # if useradd exists
                if [ -n "$(command -v "useradd")" ]
                then
                    question="do you want me to make a regular user for you? [y/n]";answer=''
                    while true; do
                        echo "$question"; read response
                        case "$response" in
                            [Yy]* ) answer='yes'; break;;
                            [Nn]* ) answer='no'; break;;
                            * ) echo "Please answer yes or no.";;
                        esac
                    done

                    if [ "$answer" = 'yes' ]; then
                        echo "${light_purple}Enter a username:${color_reset}"
                        read username
                        if sudo useradd --create-home "$username" --password "password" --groups sudo
                        then
                            echo ""
                            echo "user created successfully"
                            echo "run:"
                            echo "    ${cyan}sudo passwd "$username"${color_reset}"
                            echo "to set the password"
                        else
                            echo ""
                            echo "Sorry, there was an error when creating the user"
                            echo "I used this command: ${cyan}sudo useradd --create-home "'"'"$username"'"'" --password 'password' --groups sudo${color_reset}"
                        fi
                    else
                        echo "Okay"
                    fi
                fi

            fi
            echo ""
            echo "login as the non-root user (${cyan}su USERNAME${color_reset})"
            echo "then re-run this command"
            exit
        fi
    fi

    #       
    # MacOS 
    #
    if [ "$(uname)" = "Darwin" ]
    then
        debugging_info="$debugging_info$newline""I think you have a Mac because "'"$OSTYPE" = "darwin"*'" came back true"
        full_version="$(sw_vers -productVersion)"
        major_version="$(echo "$full_version" | sed -E 's/([0-9]+)\.[0-9]+(\.[0-9]+)?/\1/g')"
        minor_version="$(echo "$full_version" | sed -E 's/[0-9]+\.([0-9]+)(\.[0-9]+)?/\1/g')"
        #                  
        # Big Sur or Newer
        #                 
        if [ "$major_version" = "11" ] || \
            [ "$major_version" = "12" ] || \
            [ "$major_version" = "13" ] || \
            [ "$major_version" = "14" ] || \
            [ "$major_version" = "15" ]
        then
            yes | bash <(curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install) --darwin-use-unencrypted-nix-store-volume || sh <(curl -L https://nixos.org/nix/install) --daemon
        #                  
        # Older than Big Sur (Catalina, Mojave, High Siera, Siera, etc)
        #                 
        elif [ "$major_version" -eq "10" ]; then
            # Catalina
            if [ "$minor_version" = "15" ]; then
                sh <(curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install) --darwin-use-unencrypted-nix-store-volume
            # Mojave, High Siera, Siera, and might work on even older versions (Yosemite, Mavericks)
            else
                # the single-user install seems to have fewer install issues
                curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install | sh -s
                # curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install | sh -s -- --daemon
            fi
        else
            echo 'We tried to get you MacOS version by running `sw_vers -productVersion`'
            echo '(which returns '"$full_version"')'
            echo "Either 1. that value is empty 2. You're on an insanely old version 3. You're on a version way way in the future from when this script was made"
        fi
    # assuming Linux/POSIX if not on MacOS
    else
        # if curl doesnt exist, try to make it exist
        if [ -z "$(command -v "curl")" ]
        then
            # if apt-get exists
            if [ -n "$(command -v "apt-get")" ]
            then
                sudo apt-get update && sudo apt-get install curl
            else
                echo "it looks like you don't have curl, please install curl then re-run this script" 1>&2
                echo "alternatively, to get nix, manually run the commands inside https://releases.nixos.org/nix/nix-2.9.2/install" 1>&2
            fi
        fi

        # if now curl exists
        if [ -n "$(command -v "curl")" ]
        then
            # check if systemd exists
            if pidof systemd
            then
                # the single-user install seems to have fewer install issues
                curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install | sh -s
                # # multi-user install if systemd exists
                # curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install | sh -s -- --daemon
            else
                # single-user install if systemd does not exist
                curl -Lk https://releases.nixos.org/nix/nix-2.9.2/install | sh -s
            fi
        fi
    fi    
fi

# if nix is still not installed
if ! [ -d "/nix/store" ]
then
    echo "$light_yellow"
    echo "|-- Problem ------------------------------------------------------------------------------------| $color_reset" 1>&2
    echo "|                                                                                               |" 1>&2
    echo "|    Looks like there was a problem installing nix :/                                           |" 1>&2
    echo "|    Hopefully there are error messages above                                                   |" 1>&2
    echo "|    If you want additional information about installing nix see:                               |" 1>&2
    echo "|         https://nixos.org/manual/nix/stable/#chap-installation                                |" 1>&2
    echo "|                                                                                               |" 1>&2
    echo "|-----------------------------------------------------------------------------------------------|" 1>&2
    echo ""
# if nix was installed (hopefully successfully)
else
    # 
    # manually update the shell environment 
    # 
    if [ -f "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]
    then
        . "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
    fi
    if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]
    then
        . "$HOME/.nix-profile/etc/profile.d/nix.sh"
    fi
    export PATH="$PATH:/nix/var/nix/profiles/default/bin/"
    export NIXPKGS_ALLOW_UNFREE=1

    # if nix-env doesnt exist
    if [ -z "$(command -v "nix-env")" ] || [ -z "$(command -v "nix-shell")" ]
    then
        echo "$light_yellow"
        echo "|-- Action Needed ------------------------------------------------------------------------------| $color_reset" 1>&2
        echo "|                                                                                               |" 1>&2
        echo "|    - Try closing/reopening your terminal and running this command again                       |" 1>&2
        echo "|      (I dont see the nix-env and nix-shell command)                                           |" 1>&2
        echo "|                                                                                               |" 1>&2
        echo "|    - If you already did that, and you're still getting this message                           |" 1>&2
        echo "|      then you might need to uninstall and reinstall nix                                       |" 1>&2
        echo "|      instructions here:                                                                       |" 1>&2
        echo "|         https://nixos.org/manual/nix/stable/#sect-single-user-installation                    |" 1>&2
        echo "|                                                                                               |" 1>&2
        echo "|-----------------------------------------------------------------------------------------------|" 1>&2
        echo ""
    else
        # 
        # get git
        # 
        if [ -z "$(command -v "git")" ]
        then
            nix-env -i git
        fi
        # git email
        if ! git config --global user.email
        then
            echo
            echo
            echo
            echo
            echo
            echo '-------------------------------------------------------------------------------------'
            echo "git needs an email (doesnt have to be valid), what email should I tell git?"
            read answer
            # if no answer
            if [ -z "$answer" ]
            then
                git config --global user.email "change@this.com"
            else
                git config --global user.email "$answer"
            fi
        fi
        # git name
        if ! git config --global user.name
        then
            echo
            echo
            echo
            echo
            echo
            echo "git needs an name (doesnt have to be a real name), what name should I tell git?"
            read answer
            # if no answer
            if [ -z "$answer" ]
            then
                git config --global user.name "MrCHANGE ME"
            else
                git config --global user.name "$answer"
            fi
        fi
    fi
    
    # 
    # interactive setup
    # 
    # if git exists
    # if inside a git repo
    if [ -d "$PWD/.git" ]
    then
        [ -n "$(command -v "clear")" ] && clear
        echo "$blue"
        echo "one moment please ..."
        echo "$color_reset"
        # run everything in a nix shell for reliability
        echo "It looks like you are inside an existing project: ($PWD)"
        # ask about mixing in another repository
        question="${light_green}Do you want to combine (mixin) another repository into this project? [y/n]${color_reset}";answer=""
        while true; do
            echo "$question"; read response
            case "$response" in
                [Yy]* ) answer="yes"; break;;
                [Nn]* ) answer="no"; break;;
                * ) echo "Please answer yes or no";;
            esac
        done
        echo ""
        if [ "$answer" = "no" ]
        then
            echo "okay"
            # check if file exists
            if [ -f "./commands/start" ]
            then
                echo "You can run ${cyan}commands/start${color_reset} to get into the current project environment"
            fi
        fi
        if [ "$answer" = "yes" ]
        then
            if [ -z "$repo" ]
            then
                repo="https://github.com/jeff-hykin/fornix"
                echo "$light_green"
                echo "What is the URL of the repository?"
                echo "${cyan}(press enter to go with the default: $repo)"
                echo "$color_reset"
                read answer
                if [ -n "$answer" ]
                then
                    repo="$answer"
                fi
            fi
            
            # 
            # get branch
            # 
            if [ -z "$branch" ]
            then
                branch="master"
                echo "$light_green"
                echo "Which branch would you like to get?"
                echo "${cyan}(press enter to go with the default: $branch)"
                echo "$color_reset"
                read answer
                if [ -n "$answer" ]
                then
                    branch="$answer"
                fi
            fi
            
            # 
            # get mixin name
            # 
            if [ -z "$mixin_remote_name" ]
            then
                mixin_remote_name="@mixin"
                echo ""
                echo "(advanced: press enter to skip)"
                echo "    When mixing-in another repo, a remote source is added to git"
                echo "    If you want the git remote to be called something other than $mixin_remote_name"
                echo "    enter the name now (if not, press enter to continue)"
                echo "$color_reset"
                read answer
                if [ -n "$answer" ]
                then
                    mixin_remote_name="$answer"
                fi
                [ -n "$(command -v "clear")" ] && clear
            fi
            
            # 
            # perform the mixin
            # 
            # clear out anything that used to be there
            git remote remove "$mixin_remote_name" 2>/dev/null 1>/dev/null
            # add it as a remote and start merging
            git remote add "$mixin_remote_name" "$repo" && \
                git fetch "$mixin_remote_name" "$branch" && \
                git pull --allow-unrelated-histories "$mixin_remote_name" "$branch" && \
                git submodule update --init --recursive
            
            # if failed
            if [ "$?" != "0" ]
            then
                echo "$light_red"
                echo "|-- Problem ------------------------------------------------------------------------------------| $color_reset" 1>&2
                echo "|                                                                                               |" 1>&2
                echo "|    looks like git could not add that mixin :/                                                 |" 1>&2
                echo "|    - Make sure the URL and branch name are correct                                            |" 1>&2
                echo "|      (if they are correct, hopefully there is error output above that gives a better idea as) |" 1>&2
                echo "|      (to why git could not get the repo)                                                      |" 1>&2
                echo "|    - Here is the command that had an error:                                                   |" 1>&2
                echo "|          git remote add '$mixin_remote_name' '$repo' && \                                      " 1>&2
                echo "|             git fetch '$mixin_remote_name' '$branch' && \                                      " 1>&2
                echo "|             git pull --allow-unrelated-histories '$mixin_remote_name' '$branch' && \           " 1>&2
                echo "|             git submodule update --init --recursive                                            " 1>&2
                echo "|                                                                                               |" 1>&2
                echo "|-----------------------------------------------------------------------------------------------|" 1>&2
                echo ""
            else
                # check for conflicts
                if [ -n "$(git status | grep "You have unmerged paths.")" ]
                then
                    echo "$light_yellow"
                    echo "|-- Action Needed ------------------------------------------------------------------------------| $color_reset" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|    Looks like you have a merge conflict (no big deal)                                         |" 1>&2
                    echo "|    - Get the merge finished, and the mixin will be complete!                                  |" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|    Not sure how to resolve a merge conflict?                                                  |" 1>&2
                    echo "|    - How to resolve merge conflicts in VS Code:                                               |" 1>&2
                    echo "|          https://www.youtube.com/watch?v=QmKdodJU-js                                          |" 1>&2
                    echo "|    - How to resolve merge conflicts in command line:                                          |" 1>&2
                    echo "|          https://phoenixnap.com/kb/how-to-resolve-merge-conflicts-in-git                      |" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|-----------------------------------------------------------------------------------------------|" 1>&2
                    echo ""
                else
                    echo "$light_yellow"
                    echo "|-- Success! -----------------------------------------------------------------------------------| $color_reset" 
                    echo "|                                                                                               |" 
                    echo "|    - Looks like the mixin was successful!                                                     |" 
                    echo "|                                                                                               |" 
                    
                    # check if file exists
                    if [ -f "./commands/start" ]
                    then
                        echo "|   You can run ${cyan}commands/start${color_reset} to get into the project environment now                          |" 
                        echo "|                                                                                               |" 
                    fi
                    echo "|-----------------------------------------------------------------------------------------------|" 
                    echo ""
                fi
            fi
        fi
    # 
    # setup or copy
    # 
    else
        echo ""
        echo ""
        echo ""
        [ -n "$(command -v "clear")" ] && clear
        echo "$light_purple"
        echo "You're currently in this folder:"
        echo "$color_reset"
        echo "    $PWD"
        echo "$light_green"
        echo "I'm going to download the project here, okay?"
        echo "$cyan(press enter to continue, Ctrl+C to cancel)"
        echo "$color_reset"
        read answer
        [ -n "$(command -v "clear")" ] && clear
        
        # 
        # get repo URL
        # 
        if [ -z "$repo" ]
        then
            repo="https://github.com/jeff-hykin/fornix"
            echo "$light_green"
            echo "What is the URL of the repository?"
            echo "${cyan}(press enter to go with the default: $repo)"
            echo "$color_reset"
            read answer
            if [ -n "$answer" ]
            then
                repo="$answer"
            fi
        fi
        
        # 
        # get branch
        # 
        if [ -z "$branch" ]
        then
            branch="master"
            echo "$light_green"
            echo "Which branch would you like to get?"
            echo "${cyan}(press enter to go with the default: $branch)"
            echo "$color_reset"
            read answer
            if [ -n "$answer" ]
            then
                branch="$answer"
            fi
        fi
        
        # 
        # setup or copy
        #
        if [ -z "$setup_or_copy" ]
        then
            echo "Last question"
            question="$light_green""Do you want to setup or copy?${newline}$color_reset    1) if you (or your team) made this => setup${newline}    2) if the URL is a template => copy";answer=''
            while true; do
                echo "$question"; read response
                case "$response" in
                    [1]* ) answer='setup'; break;;
                    [2]* ) answer='copy'; break;;
                    "copy" ) answer='copy'; break;;
                    "setup" ) answer='setup'; break;;
                    * ) echo "${newline}${newline}${light_yellow}Please answer with a 1 or 2${color_reset}${newline}${newline}";;
                esac
            done
            setup_or_copy="$answer"
        fi
        
        folder_name="$(basename "$repo")"
        if [ -e "$folder_name" ]
        then
            echo "$light_red"
            echo "|-- Problem ------------------------------------------------------------------------------------| $color_reset" 1>&2
            echo "|                                                                                               |" 1>&2
            echo "|    - I was going to create the project in '$folder_name'                                       " 1>&2
            echo "|      But it looks like something named $folder_name already exists                             " 1>&2
            echo "|    - Please move or delete it the re-run the command you just ran                             |" 1>&2
            echo "|                                                                                               |" 1>&2
            echo "|-----------------------------------------------------------------------------------------------|" 1>&2
            echo ""
        else
            # if setup
            if [ "$setup_or_copy" = "setup" ]
            then
                echo "$light_green"
                echo "# "
                echo "# Setting up the '$branch' brach of $repo"
                echo "# "
                echo "$color_reset"
                if git clone --branch "$branch" "$repo" "$folder_name" && cd "$folder_name"
                then
                    # check if file exists
                    if [ -f "./commands/start" ]
                    then
                        echo ""
                        echo "Great! looks like it worked"
                        echo "${light_green}Any time you want to enter your project environment run these two commands"
                        echo "${cyan}"
                        echo "    cd $(printf '%s' "'$(printf '%s' "$PWD" | sed 's/'"'"'/'"'"'"'"'"'"'"'"'/g')'")"
                        echo "    commands/start"
                        echo "${color_reset}"
                        echo "Press enter to start the project"
                        read REPLY
                        echo "[starting project setup...]"
                        commands/start
                    fi
                else
                    echo "$light_red"
                    echo "|-- Problem ------------------------------------------------------------------------------------| $color_reset" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|    - it looks like there was an error when trying to get the repo                             |" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|    - here's the command I ran that caused an error                                            |" 1>&2
                    echo "|   ${cyan}git clone --branch '$branch' '$repo' '$folder_name' && cd '$folder_name'${color_reset}" 1>&2
                    echo "|                                                                                               |" 1>&2
                    echo "|-----------------------------------------------------------------------------------------------|" 1>&2
                    echo ""
                fi
            # if copy
            else
                echo "$light_green"
                echo "# "
                echo "# Creating new empty repository"
                echo "# "
                echo "$color_reset"
                mkdir -p "$folder_name"
                cd "$folder_name"
                git init && \
                    echo "$newline$light_green#$newline# Copying the '$branch' branch of $repo${newline}#${color_reset}" && \
                    git pull "$repo" "$branch" && {
                        echo "$light_purple"
                        echo "Project copied"
                        echo "$color_reset"
                        # check if file exists
                        if [ -f "./commands/start" ]
                        then
                            echo ""
                            echo "Great! looks like it worked"
                            echo "${light_green}Any time you want to enter your project environment run these two commands"
                            echo "${cyan}"
                            echo "    cd $(printf '%s' "'$(printf '%s' "$PWD" | sed 's/'"'"'/'"'"'"'"'"'"'"'"'/g')'")"
                            echo "    commands/start"
                            echo "${color_reset}"
                            echo "Press enter to start the project"
                            read REPLY
                            echo "[starting project setup...]"
                            commands/start
                        fi
                    }
            fi
        fi
    fi
fi

# cleanup the variables
unset repo; unset branch; unset mixin_remote_name;

}
