#!/bin/bash
set -e

# This is a wrapper script that runs the specific version of Android Studio that is recommended for developing in this repository.
# (This serves a similar purpose to gradlew)


function getStudioUrl() {
  propertiesFile="${scriptDir}/studio_versions.properties"
  version="$(grep "studio_version=" ${propertiesFile} | sed 's/[^=]*=//')"
  ideaMajorVersion="$(grep "idea_major_version=" ${propertiesFile} | sed 's/[^=]*=//')"
  buildNumber="$(grep "studio_build_number=" ${propertiesFile} | sed 's/[^=]*=//')"
  osName="$1"
  if [ "${osName}" == "linux" ]; then
    extension="tar.gz"
  else
    extension="zip"
  fi
  studioUrl="https://dl.google.com/dl/android/studio/ide-zips/${version}/android-studio-ide-${ideaMajorVersion}.${buildNumber}-${osName}.${extension}"
  echo "${studioUrl}"
}

acceptsLicenseAgreement="$1"
scriptDir="$(cd $(dirname $0) && pwd)"
projectDir=$scriptDir
tempDir="${scriptDir}/studio"
function getOsName() {
  unameOutput="$(uname)"
  osName=""
  if [ "${unameOutput}" == "Linux" ]; then
    osName="linux"
  else
    osName="mac"
  fi
  echo "${osName}"
}
osName="$(getOsName)"
studioUrl="$(getStudioUrl $osName)"
studioDestName="$(basename ${studioUrl})"
studioZipPath="${tempDir}/${studioDestName}"
studioUnzippedPath="$(echo ${studioZipPath} | sed 's/\.zip$//' | sed 's/\.tar.gz$//')"

function error_exit {
    echo "$1" >&2   ## Send message to stderr.
    exit 1
}

function downloadFile() {
  fromUrl="$1"
  destPath="$2"
  tempPath="${destPath}.tmp"
  if [ -f "${destPath}" ]; then
    read -r -n 1 -p "File already exists. Do you want to delete and re-download? [Y/n]? " reply

    if [ ! -z "${reply}" ]; then
      # Fix missing newline
      echo
    fi

    case "${reply}" in
      [yY]|"")
        rm "${destPath}"
        ;;
      *)
    esac
  fi

  if [ -f "${destPath}" ]; then
    echo "Using existing file from ${destPath}"
  else
    echo "Downloading ${fromUrl} to ${destPath}"
    curl "${fromUrl}" > "${tempPath}"
    mv "${tempPath}" "${destPath}"
  fi
}

function findStudioMacAppPath() {
  echo "$(find "${studioUnzippedPath}" -type d -depth 1 -name "Android Studio*.app")"
}

function getLicensePath() {
  if [ "${osName}" == "mac" ]; then
    appPath="$(findStudioMacAppPath)"
    echo "${appPath}/Contents/Resources/LICENSE.txt"
  else
    echo "${studioUnzippedPath}/android-studio/LICENSE.txt"
  fi
}

function checkLicenseAgreement() {
  # TODO: Is there a more official way to check that the user accepts the license?

  licenseAcceptedPath="${studioUnzippedPath}/STUDIOW_LICENSE_ACCEPTED"

  if [ ! -f "${licenseAcceptedPath}" ]; then
    if [ "${acceptsLicenseAgreement}" == "-y" ]; then
      touch "${licenseAcceptedPath}"
    else
      read -r -n 1 -p "Do you accept the license agreement at $(getLicensePath) [Y/n]? " reply

      if [ ! -z "${reply}" ]; then
	# Fix missing newline
        echo
      fi

      case "${reply}" in
        [yY]|"")
          touch "${licenseAcceptedPath}"
          ;;
        *)
          exit 1
          ;;
      esac
    fi
  fi
}

function updateStudio() {
  # skip if already up-to-date
  if stat "${studioUnzippedPath}" >/dev/null 2>/dev/null; then
    # already up-to-date
    return
  fi

  mkdir -p "${tempDir}"
  downloadFile "${studioUrl}" "${studioZipPath}"
  echo

  echo "Removing previous installations"
  ls "${tempDir}" | grep -v "^${studioDestName}\$" | sed "s|^|${tempDir}/|" | xargs rm -rf

  echo "Unzipping"
  if [ "${osName}" == "linux" ]; then
    mkdir $studioUnzippedPath
    tar -xzf "${studioZipPath}" --directory "${studioUnzippedPath}"
  else
    unzip "${studioZipPath}" -d "${studioUnzippedPath}"
  fi
}

function ensureComposeAt() {
  pluginPath=$1
  copyOption=$2
  idePluginJar="$pluginPath/r4a-ide-plugin.jar"
  compilerPluginJar="$pluginPath/r4a-compiler-plugin.jar"
  compilerPluginJarOutput="androidx_prebuilts/out/ui/build/support_repo/androidx/compose/compose-plugin-cli/0.1.0-dev01/compose-plugin-cli-0.1.0-dev01.jar"
  idePluginJarOutput="androidx_prebuilts/out/ui/build/support_repo/androidx/compose/compose-plugin-ide/0.1.0-dev01/compose-plugin-ide-0.1.0-dev01.jar"
  if [ ! -e "$idePluginJarOutput" ] || [ ! -e "$compilerPluginJarOutput" ]
  then
    echo "Building compose plugin"
    ./gradlew :compose-plugin-ide:assemble :compose-plugin-cli:ideVersion
  fi
  cp $copyOption "$compilerPluginJarOutput" "$compilerPluginJar"
  cp $copyOption "$idePluginJarOutput" "$idePluginJar"
}

function ensureComposeLinux() {
  ensureComposeAt "${studioUnzippedPath}/android-studio/plugins/Kotlin/lib" "-u"
}

function ensureComposeMac() {
  ensureComposeAt "$(findStudioMacAppPath)/Contents/plugins/Kotlin/lib"
}

function ensureCompose() {
  # ensure compose plugin is up-to-date
  if [ "${osName}" == "mac" ]; then
    ensureComposeMac
  else
    ensureComposeLinux
  fi
}

function runStudioLinux() {
  studioPath="${studioUnzippedPath}/android-studio/bin/studio.sh"
  echo "$studioPath &"
  env STUDIO_PROPERTIES="${projectDir}/idea.properties" \
      STUDIO_VM_OPTIONS="${projectDir}/../development/studio/studio.vmoptions" \
      KOTLIN_OVERRIDE="1.3.30-compose-20190503" \
      "${studioPath}" "${projectDir}" &
}

function runStudioMac() {
  appPath="$(findStudioMacAppPath)"
  echo "open ${appPath}"
  env STUDIO_PROPERTIES="${projectDir}/idea.properties" \
      STUDIO_VM_OPTIONS="${projectDir}/../development/studio/studio.vmoptions" \
      KOTLIN_OVERRIDE="1.3.30-compose-20190503" \
      open -a "${appPath}" "${projectDir}"
}

function runStudio() {
  if [ "${osName}" == "mac" ]; then
    runStudioMac
  else
    runStudioLinux
  fi
}

function main() {
  updateStudio
  ensureCompose
  checkLicenseAgreement
  runStudio
}

main
