#!/usr/bin/env fish
#
# USAGE
#   #1: curl -L github.com/oh-my-fish/oh-my-fish/raw/master/bin/install | fish
#   #2: curl -L github.com/oh-my-fish/oh-my-fish/raw/master/bin/install > install; and fish install
#   #3: env OMF_CONFIG=~/.omf curl -L github.com/oh-my-fish/oh-my-fish/raw/master/bin/install | fish
#
# ENV
#   XDG_DATA_HOME       Base directory (~/.local/share)
#   XDG_CONFIG_HOME     Base configuration directory (~/.config)
#
#   - See XDG Base Directory Specification:
#   - https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
#
#   FISH_CONFIG       Fish shell configuration file
#
#   OMF_PATH          Oh My Fish installation directory
#   OMF_CONFIG        Oh My Fish configuration directory
#
#   OMF_REPO_URI      Oh My Fish source git repository
#   OMF_REPO_BRANCH   Oh My Fish source repository branch


set -q XDG_DATA_HOME;   or set XDG_DATA_HOME "$HOME/.local/share"
set -q XDG_CONFIG_HOME; or set XDG_CONFIG_HOME "$HOME/.config"

set -q FISH_CONFIG;     or set FISH_CONFIG "$XDG_CONFIG_HOME/fish"

set -q OMF_PATH;        or set OMF_PATH "$XDG_DATA_HOME/omf"
set -q OMF_CONFIG;      or set OMF_CONFIG "$XDG_CONFIG_HOME/omf"

set -q OMF_REPO_URI;    or set OMF_REPO_URI "https://github.com/oh-my-fish/oh-my-fish"
set -q OMF_REPO_BRANCH; or set OMF_REPO_BRANCH "master"

set OMF_FISH_MIN_VER 2 1 0

function available -a name
  type "$name" >/dev/null 2>&1
end

function report -a what message
  switch $what
  case 'progress'
    set_color yellow
  case 'success'
    set_color green
  case 'error'
    set_color red
    printf "$message\n"
    exit 1
  end

  printf "$message\n"
end

function fish_version_compatible
  set -l major (echo $version | cut -d. -f1)
  set -l minor (echo $version | cut -d. -f2)

  return (test $major = $OMF_FISH_MIN_VER[1] -a $minor -ge $OMF_FISH_MIN_VER[2])
end


function backup_file -a file_path
  test -e "$file_path"; or return 1

  set -l path (dirname $file_path)
  set -l file (basename $file_path)
  set -l name (echo $file | cut -d. -f1)

  set -l timestamp (date +%s)
  set -l backup_file "$path/$name.$timestamp.copy"

  report progress "Existent $file found at $path"
  report progress "↳ Moving to $backup_file"

  if not mv "$file_path" $backup_file 2>/dev/null
    report error "Aborting: Could not backup $file_path"
  end

  return 0
end

function install_omf
  # Grant repository URL ends with .git
  set git_uri (echo $OMF_REPO_URI | sed 's/\.git//').git

  report progress "Cloning $OMF_REPO_BRANCH from $git_uri..."
  if not git clone -q --depth 1 -b $OMF_REPO_BRANCH $git_uri "$OMF_PATH"
    report error "Error cloning repository!"
  end

  set git_upstream (git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" config remote.upstream.url)

  if test -z "$git_upstream"
    git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" remote add upstream $git_uri
  else
    git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" remote set-url upstream $git_uri
  end

  set fish_config_file "$FISH_CONFIG/config.fish"

  backup_file "$FISH_CONFIG/config.fish";
    or mkdir -p "$FISH_CONFIG"

  backup_file "$FISH_CONFIG/functions/fish_prompt.fish"

  report progress "Adding startup code to fish config file..."

  set template "templates/config.fish"
  set replacements "s|{{OMF_PATH}}|$OMF_PATH|;s|{{OMF_CONFIG}}|$OMF_CONFIG|"

  if test "$OMF_CONFIG" != "$XDG_CONFIG_HOME/omf"
    set replacements "$replacements;s|#set|set|"
  end

  sed  "$replacements" "$OMF_PATH/$template" > "$fish_config_file"

  report progress "Building Oh My Fish configuration..."

  if not test -d "$OMF_CONFIG"
    mkdir -p "$OMF_CONFIG"
  end

  test -f "$OMF_CONFIG/bundle"; or echo "theme default" > "$OMF_CONFIG/bundle"
  test -f "$OMF_CONFIG/theme";  or echo "default" > "$OMF_CONFIG/theme"

  fish -c "omf install"
end

function main
  report progress "Installing Oh My Fish to $OMF_PATH..."

  if test -d "$OMF_PATH"
    report error "Aborting: Existing installation detected."
  end

  if not available git
    report error "Aborting: Installation requires Git."
  end

  if not fish_version_compatible
    set -l minimum_version_string (echo $OMF_FISH_MIN_VER | sed 's/ /./g')
    report error "Aborting: Detected fish $version, but Oh My Fish requires fish $minimum_version_string or greater."
  end

  if install_omf
    report success "Installation successful!"
    set -q CI; or exec fish < /dev/tty
  else
    report error "Oh My Fish installation failed.\n\nIf you think that it's a bug, please open an\nissue with the complete installation log here:\n\nhttp://github.com/oh-my-fish/oh-my-fish/issues"
  end

  exit 0
end

main