#!/usr/bin/env bash

perform()
{
  enter "${initial_pwd}"
  "$*"
}

prepare_for_installation()
{
  local directory

  log "  Ensuring that install_path '${install_path}' exists"
  ensure_paths_exist "${install_path}"
  enter "${install_path}"

  log "  Cleansing installation path"
  for directory in "${cleanse_paths[@]}"
  do
    if path_exists "./${directory}"
    then
      rm -rf "./${directory}"
    fi
  done

  log "  Creating installation paths"
  ensure_paths_exist "${directories[@]}" "${aux_paths[@]}"
}

# make a copy of provided bdsm internal extensions if there is none
install_internal_extensions()
{
  if path_exists "${install_path}/extensions/internal" &&
    file_exists "${install_path}/extensions/internal/.uri" &&
    file_contains "${install_path}/extensions/internal/.uri" "/bdsm-extensions"
  then
    log "\n  To update internal extensions use 'bdsm internal update'\n"
  else
    if path_exists "extensions/internal" &&
      file_exists "extensions/internal/README.md"
    then
      log "  Installing internal extensions"
    else
      log "  Downloading & installing internal extensions"
      mkdir -p "extensions/internal"
      git submodule init
      git submodule update
    fi
    copy_directory "extensions/internal" to "${install_path}/extensions/internal"
    write "wayneeseguin/bdsm-extensions" to "${install_path}/extensions/internal/.uri"
  fi
}

migrate_external_extensions()
{
  log "  Migrating external extensions"
  enter "${install_path}/extensions"
  ensure_paths_exist external
  for extension in *
  do
    # skip new directories
    case ${extension} in
      builtin|internal|external)
        continue
        ;;
    esac
    if file_exists "${extension}/.uri" &&
      file_contains "${extension}/.uri" "git://github.com/wayneeseguin/bdsm-extensions"
    then
      # old internal extension
      remove "${extension}"
    else
      # external extension
      move_directory "${extension}" "external/${extension}"
      if file_exists "external/${extension}/.uri"
      then
        sed -ie "s/git:\/\/github.com\/\(.*\)\.git/\1/" "external/${extension}/.uri"
      fi
    fi
  done
}

install_core()
{
  local _dir
  log "  Installing core directories (${directories[*]}) into ${install_path}"

  copy_paths --force to "${install_path}/" "${directories[@]}"

  log "  Installing core files (${files[*]}) into ${install_path}"
  copy_files to "${install_path}" ${files[@]}

  log "  Installing builtin extensions"
  copy_paths --force to "${install_path}/extensions/" "extensions/builtin"

}

install_configuration_files()
{
  log "  Ensuring that the configuration files (${configs[*]}) exist in ${install_path}"
  for config_file in "${configs[@]}"
  do
    ensure_files_exist "${install_path}/config/${config_file}"
  done
}

symlink_bdsm()
{
  log "  Linking ${install_path}/bin/bdsm to ${prefix_path}/bin/bdsm"
  link --force "${install_path}/bin/bdsm" to "${prefix_path}/bin/bdsm"

  if path_exists "${prefix_path}/bin"
  then
    link --force "${install_path}/bin/bdsm" to "${prefix_path}/bin/bdsm"
  fi
}

setup_shell_completion()
{
  if user_is_root
  then
    log "  Setting up bdsm shell completion."

    if path_exists "/etc/bash_completion.d"
    then
      completion_prefix="/etc/bash_completion.d"
    else
      completion_prefix="/etc/profile.d"
      ensure_paths_exist "/etc/profile.d/"
    fi

    copy_file \
      from "${install_path}/extensions/builtin/bdsm/modules/shell/completion/bash" \
      to "${completion_prefix}/bdsm-completion.sh" \
      mode 0755 owner "root"
  fi
}

setup_profile_d()
{
  ensure_paths_exist "${profile_d_path}"

  if user_is_root
  then
    if os_is_darwin
    then
      if ! file_contains /etc/profile "${profile_d_path}"
      then
        write "\nif test -d '${profile_d_path}' ; then for profile in \"${profile_d_path}\"/*.sh ; do if test -x \"\$profile\" ; then . \"\$profile\" ; fi ; done ; unset profile ; fi\n" \
          to /etc/profile
      fi
    fi
  else
    ensure_files_exist "$HOME/.profile" "$HOME/.bashrc" "$HOME/.bash_profile"

    if ! file_contains "$HOME/.bashrc" "$HOME/.profile"
    then
      write "if test -s \"$HOME/.profile\" ; then . \"$HOME/.profile\" ; fi"\
        append to "$HOME/.bashrc"
    fi

    if ! file_contains "$HOME/.bash_profile" "$HOME/.bashrc"
    then
      write "if test -s \"$HOME/.bashrc\" ; then . \"$HOME/.bashrc\" ; fi"\
        append to "$HOME/.bash_profile"
    fi

    if ! file_contains "$HOME/.profile" "${profile_d_path}"
    then
      write "\nif test -d '${profile_d_path}' ; then for profile in \"${profile_d_path}\"/*.sh ; do if test -x \"\$profile\" ; then . \"\$profile\" ; fi ; done ; unset profile ; fi\n" \
        append to "$HOME/.profile"
    fi
  fi

  if ! file_exists "${profile_d_path}/bdsm.sh" ||
     ! file_contains "${profile_d_path}/bdsm.sh" "${packages_path}/active/bin"
  then
    # To prepend or postpend??? Good discussion here...
    write "PATH=\"${packages_path}/active/bin:${packages_path}/active/sbin:\${PATH}\"\n" \
      to "${profile_d_path}/bdsm.sh"

    chmod_files 0755 "${profile_d_path}/bdsm.sh"
  fi
}

set_bdsm_path()
{
  replace_content "^bdsm_path=.*" with "bdsm_path=\"${install_path}\"" in "${install_path}/bin/bdsm"
  replace_content "^saved_bdsm_path=.*" with "saved_bdsm_path=\"\${bdsm_path:-${install_path}}\"" \
    in "${install_path}/extensions/builtin/core/modules/shell/core/initialize"
}

install_bdsm()
{
  log "Installing BDSM Framework into ${install_path}\n"

  prepare_for_installation

  perform install_core

  perform set_bdsm_path

  perform install_internal_extensions

  perform migrate_external_extensions

  perform install_configuration_files

  perform symlink_bdsm

  perform setup_shell_completion

  perform setup_profile_d

  succeed "\nInstallation of BDSM is complete\n"
}
