#!/usr/bin/env bash

set -e

command:setup() {
  setup:intro
  setup:login
  setup:api-token
  setup:use-auth
  setup:json-perl
  setup:outro
  exit 0
}

setup:intro() {
  clear
  cat <<...

                        The 'git hub' Setup Tool

This dialog will walk you through the steps involved in creating or updating
the configuration needed by the 'git hub' command. It should only take a
minute.

Your config will be stored here: '$GIT_HUB_CONFIG'.

...
  prompt
  mkdir -p "$GIT_HUB_USER_DIR"
}

setup:login() {
  clear
  cat <<...

                        Step #1 - Login ID

The 'git hub' command needs to know your GitHub login id.

...
  read-config-value login && login="$value" || login=
  if [ -n "$login" ]; then
    echo "Your login is currently set to '$login'".
    echo
    a="$(prompt "Do you want to keep this value? [Yn] ")"
    [ "$a" == y ] && return
  fi

  while true; do
    echo
    login="$(prompt "Enter your GitHub login id: ")"
    [[ "$login" =~ ^[-a-zA-Z0-9]+$ ]] && break
    echo "Invalid login value '$login'"
  done

  write-config-value login "$login" ||
    die "Can't write-config-value login $login"

  cat <<...

Login changed to '$login'.

...
  prompt
}

setup:api-token() {
  clear
  cat <<...

                        Step #2 - API Token

More advanced commands require an authentication token (with the appropriate
scopes added).
...
  read-config-value api-token && token="$value" || token=
  if [ -n "$token" ]; then
    cat <<...

It seems that you already have a token. To see your token, run these commands:

    git hub config api-token
    git hub token-list

Verify that this is the correct token, If not, we will generate a new token
for you and put it in the config file.

...
    a="$(prompt "Is this the correct token? [Yn]")"
    [ "$a" == y ] && return
  fi
  cat <<...

To generate a new token, the commands require your GitHub password.

The password will not be stored after the commands finish running.
...
  export GIT_HUB_PASSWORD="$(
    prompt "Enter your GitHub password (for '$login'): "
  )"
  echo
  echo
  echo 'Generating a new authentication token...'

  local rc=0 token_id= desc="API Token for git-hub ($(date "+%s"))"

  token_id="$(git hub token-new -qr "$desc")" || rc=$?
  if [ "$rc" -eq 2 ]; then
    export GIT_HUB_2FA_OTP="$(
      prompt "Enter your 2 Factor Auth Code: "
    )"
    token_id="$(git hub token-new -qr "$desc")" || true
  fi
  [ -n "$token_id" ] || die "Command failed"
  echo "Token successfully generated (token id: $token_id)."
  echo
  echo "Adding the 'user', 'repo' and 'gist' scopes to the token..."
  $(git hub scope-add $token_id user repo gist &> /dev/null) || exit $?
  echo "Scopes successfully added."
  echo
  echo "Adding the new token to your config file..."
  local token_value="$(git hub token-get $token_id token)" || exit $?
  write-config-value api-token $token_value ||
    die "Can't write-config-value api-token $token_value"
  echo "Token successfully added to config file."
  echo
  prompt
  unset GIT_HUB_PASSWORD
}

setup:use-auth() {
  clear
  cat <<...

                        Step #3 - Use Authentication

Many commands don't require you to send your authentication token, but there
are a couple reasons why you might want to send it anyway.

1) Some information about users and repositories is only provided for
   authenticated requests.

2) GitHub only allows 60 unauthenticated calls per hour, as opposed to 5000
   for authenticated calls. For this reason it is preferable to always
   authenticate.

There is a config option called 'use-auth' that you can set to always send the
authentication token.

...
  read-config-value use-auth && auth="$value" || auth=
  if [ -z "$auth" ]; then
    a="$(prompt "Would you like to turn this option on? [Yn]")"
    [ "$a" == n ] && return
  elif [ "$auth" == false ]; then
    echo 'You have this option turned off.'
    echo
    a="$(prompt "Would you like to turn this option on? [yN]")"
  else
    write-config-value use-auth true ||
      die "Can't write-config-value use-auth true"
    echo 'You already have this option turned on.'
    echo
    a="$(prompt "Would you like to keep this option on? [Yn]")"
  fi
  if [ "$a" == y ]; then
    write-config-value use-auth true ||
      die "Can't write-config-value use-auth true"
  else
    write-config-value use-auth false ||
      die "Can't write-config-value use-auth false"
  fi
}

setup:json-perl() {
  clear

  local perl="$(perl -e 'print "OK"' 2> /dev/null)"
  local perl_json_pp="$(perl -MJSON::PP -e 'print "OK"' 2> /dev/null)"
  local perl_json="$(perl -MJSON -e 'print "OK"' 2> /dev/null)"
  local perl_json_maybexs="$(
    perl -MJSON::MaybeXS -e 'print "OK"' 2> /dev/null
  )"
  read-config-value json-lib && set="$value" || set=
  local a=

  cat <<...

                        Step #4 - Faster JSON

The 'git-hub' command is written entirely in Bash. The Bash JSON utility it
uses can be slow.

There is a setting to use Perl to handle the JSON which is much faster. It
requires Perl and the JSON::MaybeXS modules for Perl.

...
  if [ -n "$set" ]; then
    cat <<...
You already have this option set to '$set'.

...
    prompt
  elif [ "$perl" == OK ]; then
    if [ "$perl_json_pp" == OK ] ||
       [ "$perl_json" == OK ] ||
       [ "$perl_json_maybexs" == OK ]
    then
      cat <<...
You seem to have the prerequisites to speed up your 'git-hub' experience.

...
      a="$(prompt "Would you like to turn this setting on? [Yn]")"
      [ "$a" == y ] && write-config-value json-lib json-perl.bash ||
        die "Can't write-config-value use-auth false"
    else
      cat <<...
You seem to have Perl, but none of the 'JSON::MaybeXS', 'JSON' or 'JSON::PP'
modules, so we can't use the setting at this time.

Try installing the JSON::MaybeXS module from CPAN and then run 'git hub setup'
again.

...
      prompt
    fi
  else
    cat <<...
Perl seems to not be installed on your system, so we can't use the setting at
this time.

If you want to use this speedup in the future, try installing Perl and the
JSON::MaybeXS module from CPAN and then run 'git hub setup' again.

...
    prompt
  fi
}

setup:outro() {
  clear
  cat <<'...'

                        Setup Complete

The setup process is now complete!

To see your new config, run this command:

    git hub config

You should now be able to run almost all 'git hub' commands.

For more advanced configuration commands, see the complete documentation:

    git help hub

Enjoy GitHubbing from the command line!

...
}
