{ # <- Prevent execution if this script was only partially downloaded

# dependencies (some depend on the OS): command, uname, echo, sed, sh, curl, sw_vers, pidof, whoami, mktemp, rm, basename, xz, mkdir, tar

# setup some helpers
newline='
'
light_yellow="\e[0;1;33m";light_yellow=""
light_purple="\e[0;1;35m";light_purple=""
light_green="\e[0;1;32m";light_green=""
light_red="\e[0;1;31m";light_red=""
blue="\e[0;94m"; blue=""
cyan="\e[0;36m";cyan=""
color_reset="\e[0m";color_reset=""

# saftey/cleanup
# if trap exists
if [ -n "$(command -v "trap")" ]
then
    trap 'unset repo; unset branch; unset setup_or_copy; unset mixin_remote_name; exit 0' INT TERM
fi
        
# if nix doesnt exist
if [ -z "$(command -v "nix")" ]
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
            bash <(curl -Lk https://releases.nixos.org/nix/nix-2.3.7/install) --darwin-use-unencrypted-nix-store-volume
        #                  
        # 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.3.7/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.3.7/install | sh -s
                # curl -Lk https://releases.nixos.org/nix/nix-2.3.7/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.3.7/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.3.7/install | sh -s
                # # multi-user install if systemd exists
                # curl -Lk https://releases.nixos.org/nix/nix-2.3.7/install | sh -s -- --daemon
            else
                # single-user install if systemd does not exist
                curl -Lk https://releases.nixos.org/nix/nix-2.3.7/install | sh -s
            fi
        fi
    fi
fi

# if nix was 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/"
    
    # 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 "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 "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
        
        # 
        # 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
    
fi

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

} # end: <- Prevent execution if this script was only partially downloaded
