#!/usr/bin/env bash

# Default Python Versions
# shellcheck source=bin/default_pythons
source "bin/default_pythons"

testPythonDefault() {
  updateVersion "pythonDefault" $DEFAULT_PYTHON_VERSION
  compile "pythonDefault"
  assertCaptured $DEFAULT_PYTHON_VERSION
  assertNotCaptured "security update"
  assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
  assertCaptured "Installing SQLite3"
  assertCapturedSuccess
}

testPython2() {
    updateVersion "python2" $LATEST_27
    echo $LATEST_27 > "runtime.txt"
    compile "python2"
    assertCaptured $LATEST_27
    assertCaptured "python-2-7-eol-faq";
    assertNotCaptured "security update"
    assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
}

testPython2_warn() {
    compile "python2_warn"
    assertCaptured "python-2.7.15"
    assertCaptured "python-2-7-eol-faq";
    assertCaptured "Only the latest version"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
}

testPython3_4() {
  compile "python3_4"
  assertCaptured $LATEST_34
  assertNotCaptured "security update"
  assertCaptured "Installing pip 19.1.1, setuptools 43.0.0 and wheel 0.33.6"
  # Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
  # and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
  assertCapturedSuccessWithStdErr
}

testPython3_4_warn() {
  compile "python3_4_warn"
  assertCaptured "python-3.4.9"
  assertCaptured "security update!"
  # Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
  # and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
  assertCapturedSuccessWithStdErr
}

testPython3_5() {
  compile "python3_5"
  assertCaptured $LATEST_35
  assertNotCaptured "security update"
  assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
  assertCaptured "Installing SQLite3"
  assertCapturedSuccess
}

testPython3_5_warn() {
  compile "python3_5_warn"
  assertCaptured "python-3.5.6"
  assertCaptured "security update!"
  assertCapturedSuccess
}

testPython3_6() {
  updateVersion "python3_6" $LATEST_36
  compile "python3_6"
  assertCaptured $LATEST_36
  assertNotCaptured "security update"
  assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
  assertCaptured "Installing SQLite3"
  assertCapturedSuccess
}

testPython3_6_warn() {
  compile "python3_6_warn"
  assertCaptured "python-3.6.7"
  assertCaptured "security update!"
  assertCaptured "Installing SQLite3"
  assertCapturedSuccess
}

testPython3_7() {
  updateVersion "python3_7" $LATEST_37
  compile "python3_7"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertNotCaptured "security update"
    assertCaptured $LATEST_37
    assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
  fi
}

testPython3_7_warn() {
  compile "python3_7_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertCaptured "python-3.7.1"
    assertCaptured "security update!"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
  fi
}

testPython3_8() {
  updateVersion "python3_8" $LATEST_38
  compile "python3_8"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertNotCaptured "security update"
    assertCaptured $LATEST_38
    assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
  fi
}

testPython3_8_warn() {
  compile "python3_8_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertCaptured "python-3.8.0"
    assertCaptured "security update!"
    assertCaptured "Installing SQLite3"
    assertCapturedSuccess
  fi
}

testPython3_9() {
  # Cedar-14 is EOL, so we're not building new major Python versions for it.
  if [[ "${STACK}" = "cedar-14" ]]; then
    return
  fi
  compile "python3_9"
  assertNotCaptured "security update"
  assertCaptured $LATEST_39
  assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
  assertCaptured "Installing SQLite3"
  assertCapturedSuccess
}

testPython3_9_warn() {
  # Cedar-14 is EOL, so we're not building new major Python versions for it.
  if [[ "${STACK}" = "cedar-14" ]]; then
    return
  fi
  # Can't test the version warning until there is at least one old version of Python 3.9.
  if [[ "${LATEST_39}" = "python-3.9.0" ]]; then
    return
  fi
  compile "python3_9_warn"
  assertCaptured "python-3.9.0"
  assertCaptured "security update!"
  assertCapturedSuccess
}

testPythonVersionInvalid() {
  compile "python_version_invalid"
  assertCaptured "Requested runtime (python-3.8.99) is not available for this stack"
  assertCaptured "Aborting"
  assertCapturedError
}

testPypy3_6() {
  compile "pypy3_6"
  assertCaptured "Installing pypy"
  assertNotCaptured "security update"
  assertCaptured "$LATEST_PYPY_36"
  assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
  assertCapturedSuccess
}

testPypy3_6_warn() {
  compile "pypy3_6_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertCaptured "Installing pypy"
    assertCaptured "security update!"
    assertCaptured "$LATEST_PYPY_36"
    assertCapturedSuccess
  fi
}

testPypy2_7() {
  compile "pypy2_7"
  assertCaptured "Installing pypy"
  assertNotCaptured "security update"
  assertCaptured "$LATEST_PYPY_27"
  assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
  assertCapturedSuccess
}

testPypy2_7_warn() {
  compile "pypy2_7_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertCaptured "Installing pypy"
    assertCaptured "security update!"
    assertCaptured "$LATEST_PYPY_27"
    assertCapturedSuccess
  fi
}

testStickyPythonVersion() {
  local cache_dir="$(mktmpdir)"
  compile "python3_6_warn" "$cache_dir"
  assertCaptured "Installing python-3.6.7"
  assertCapturedSuccess
  compile "no-runtime-txt" "$cache_dir"
  assertCaptured "Installing python-3.6.7"
  assertCapturedSuccess
  # Whilst this file seems like an implementation detail (so something that should
  # not be tested), we must guarantee the filename remains consistent for backwards
  # compatibility across buildpack versions for already-built apps.
  assertFile "python-3.6.7" ".heroku/python-version"
}

testPythonVersionChange() {
  local cache_dir="$(mktmpdir)"
  compile "python3_6_warn" "$cache_dir"
  assertCaptured "Installing python-3.6.7"
  assertCapturedSuccess
  compile "python3_6" "$cache_dir"
  assertCaptured "Found python-3.6.7, removing"
  assertCapturedSuccess
}

pushd $(dirname 0) >/dev/null
popd >/dev/null

source $(pwd)/test/utils
source $(pwd)/test/shunit2
