#!/usr/bin/env bash

# CONFIGURABLE OPTIONS #################################################################################
server='https://transfer.simd.stream'
use_stdout='no'

# COMMAND PARSING #################################################################################
case "${1}" in
    download|dl|d)  cmd="download" ;;
    upload|up|ul|u) cmd="upload" ;;
    *)              cmd="${1}" ;;
esac
shift

# STDIN FRIENDLINESS ##############################################################################
case "${cmd}" in
  upload) [ -p /dev/stdin ] && stdin=$(cat <&0) ;;
esac

# ARGUMENT AND OPTION PARSING #####################################################################
while (( "$#" )); do
  case "${1}" in
    --cat) use_stdout="yes" ; shift ;;
    --decrypt|-d) decrypt=0 ; shift ;;
    --encrypt|-e) encrypt=0 ; shift ;;
    --file=*) file=${1/--file=/''} ; shift ;;
    --file*|-f*) file=${2} ; shift ; shift ;;
    --max-days=*) max_days=${1/--max-days=/''} ; shift ;;
    --max-days*|-y*) max_days=${2} ; shift ;  shift ;;
    --max-downloads=*) max_downloads=${1/--max-downloads=/''} ; shift ;;
    --max-downloads*|-l*) max_downloads=${2} ; shift ;  shift ;;
    --password=*) password=${1/--password=/''} ; shift ;;
    --password*|-p*) password=${2} ; shift ; shift ;;
    --save) use_stdout="no" ; shift ;;
    --slug=*) slug=${1/--slug=/''} ; shift ;;
    --slug*|-s*) slug=${2} ; shift ; shift ;;
    --trace|-x) trace='set -x' ; shift ;;
    --url=*) url=${1/--url=/''} ; shift ;;
    --url*|-u*) url=${2} ; shift ; shift ;;
    *)
      case "${cmd}" in
        download)
          [ -n "${1}" ] && [ -n "${url}" ] && [ -z "${file}" ] && file=${1}
          [ -n "${1}" ] && [ -z "${url}" ] && url=${1}
        ;;
        upload)
          [ -n "${1}" ] && [ -n "${file}" ] && [ -z "${slug}" ] && slug=${1}
          [ -n "${1}" ] && [ -z "${file}" ] && file=${1}
        ;;
      esac
      shift
    ;;
  esac
done

# TRACING #########################################################################################
${trace}

# ARGUMENT AND OPTION PROMPTING ###################################################################
case "${cmd}" in
  download)
    [ -z "${url}" ] && read -e -p 'Enter url (e.g. https://transfer.sh/abcXYZ/file.log): ' url
  ;;
  upload)
    [ -z "${file}" ] && read -e -p 'Enter file (e.g. /path/to/file.log): ' file
  ;;
esac

# COMMAND FUNCTIONS ###############################################################################
function download() {
  [ -z "${file}" -a "${use_stdout}" == "no" ] && file=${url##*/}

  if [ -n "${file}" ]; then
    local path=$(greadlink -f "${file}" 2> /dev/null || readlink -f "${file}" 2> /dev/null)

    curl --progress-bar "${url}" |
      ([ -z "${decrypt}" ] && cat || openssl aes-256-cbc -d -a ${password:+-k "${password}"}) > "${path}"

    echo "${path}"
    if type pbcopy &> /dev/null; then echo -n ${path} | pbcopy; fi
  else
    curl --silent "${url}" 2> /dev/null |
      ([ -z "${decrypt}" ] && cat || openssl aes-256-cbc -d -a ${password:+-k "${password}"})
  fi
}

function help() {
  local a=(${0//\// })
  local bin=${a[${#a[@]}-1]}

  echo 'Usage:'
  echo "  ${bin} download [<url> [file]]"
  echo '    [--decrypt|-d] [--file|-f <file>] [--password|-p <password>] [--trace|-x]'
  echo '    [--url|-u <url>]'
  echo
  echo "  ${bin} upload [<file> [slug]]"
  echo '    [--encrypt|-e] [--max-days|-y <days>] [--max-downloads|-l <dls>] [--file|-f <file>] [--password|-p <password>] [--slug|-s <slug>]'
  echo '    [--trace|-x]'
  echo
  echo 'Commands:'
  echo '  download    Download from transfer.sh to file or piped output'
  echo '  upload      Upload a file, directory, or piped input to transfer.sh'
  echo
  echo 'More Information:'
  echo '  chat    https://rockymadden-slack.herokuapp.com'
  echo '  repo    https://github.com/rockymadden/transfer-cli'
}

function upload() {
  ! [ -d ${file} ] && ! [ -f "${file}" ] && { echo 'File should exist' ; return 1; }
  [ -z "${file}" ] && [ -z "${stdin}" ] && { echo 'File should be provided' ; return 1; }
  [ -z "${file}" ] && [ -n "${stdin}" ] && [ -z "${slug}" ] && { echo 'Slug should be provided' ; return 1; }

  local tmpurl=$(mktemp -t transfer.url.XXXXXXXX)
  trap "rm -f ${tmpurl}" 0

  local headers=""
  [ -n "${max_days}" ] && headers="${headers}-H \"Max-Days: ${max_days}\" "
  [ -n "${max_downloads}" ] && headers="${headers}-H \"Max-Downloads: ${max_downloads}\""

  if [ -n "${file}" ]; then
    if [ -d ${file} ]; then
      [ -z "${slug}" ] && slug="$(basename ${file} | sed -e 's/[^a-zA-Z0-9._-]/-/g').tar.gz"

      local tmptar=$(mktemp -t transfer.tar.gz.XXXXXXXX)
      trap "rm -f ${tmpurl} ; rm -f ${tmptar}" 0

      (cd $(dirname ${file}); tar -zcf ${tmptar} $(basename ${file}))

      cat "${tmptar}" |
        ([ -z "${encrypt}" ] && cat || openssl aes-256-cbc -a -salt ${password:+-k "${password}"}) |
        eval curl --progress-bar "${headers}" --upload-file - "${server}/${slug}" > ${tmpurl}
    elif [ -f "${file}" ]; then
      [ -z "${slug}" ] && slug="$(basename ${file} | sed -e 's/[^a-zA-Z0-9._-]/-/g')"

      cat "${file}" |
        ([ -z "${encrypt}" ] && cat || openssl aes-256-cbc -a -salt ${password:+-k "${password}"}) |
        eval curl --progress-bar "${headers}" --upload-file - "${server}/${slug}" > ${tmpurl}
    fi
  elif [ -n "${stdin}" ]; then
    echo "${stdin}" |
      ([ -z "${encrypt}" ] && cat || openssl aes-256-cbc -a -salt ${password:+-k "${password}"}) |
      eval curl --progress-bar "${headers}" --upload-file - "${server}/${slug}" > ${tmpurl}
  fi

  cat ${tmpurl} && [ "${use_stdout}" == "no" ] && echo
  if type pbcopy &> /dev/null; then cat ${tmpurl} | tr -d '\n' | pbcopy; fi
}

function version() {
  echo 'v0.2.0'
}

# COMMAND ROUTING #################################################################################
case "${cmd}" in
  --help|-h) help ; exit 0 ;;
  --version|-v) version ; exit 0 ;;
  download|upload) ${cmd} ; exit ${?} ;;
  *) help ; exit 1 ;;
esac

