#!/usr/bin/env bash

# Copyright 2018 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

readonly SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
readonly ZIRCON_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
readonly PREBUILTS_DIR="$(cd "${ZIRCON_ROOT}/prebuilt" && pwd)"
readonly DOWNLOAD_DIR="${PREBUILTS_DIR}/downloads"
readonly ENSURE_FILE="${PREBUILTS_DIR}/zircon.ensure"
readonly VERSIONS_FILE="${PREBUILTS_DIR}/zircon.versions"
readonly URL_PREFIX="https://storage.googleapis.com/fuchsia"

# This script assumes that ENSURE_FILE and VERSIONS_FILE match up.
# The update-prebuilt-versions script ensures that they do.  When a
# cipd binary is available, ENSURE_FILE controls the downloads.
# Otherwise, VERSIONS_FILE controls the downloads.  In both cases we
# write $DOWNLOAD_DIR/$PACKAGE.stamp files with the versions from
# VERSIONS_FILE on faith that that's what we just unpacked.

cipd_ok=true
case "$#:$1" in
0:)
  mode=update
  ;;
1:--verify)
  mode=verify
  ;;
1:--list)
  mode=list
  ;;
1:--no-cipd)
  mode=update
  cipd_ok=false
  ;;
*)
  echo >&2 "Usage: $0 [--verify|--list|--no-cipd]"
  exit 1
  ;;
esac
readonly cipd_ok

case "$(uname)-$(uname -m)" in
Darwin-x86_64)
  PLATFORM=mac-amd64
  ;;
Linux-x86_64)
  PLATFORM=linux-amd64
  ;;
Linux-aarch64)
  PLATFORM=linux-arm64
  ;;
*)
  echo 'Unknown operating system.'
  exit 1
  ;;
esac
readonly PLATFORM

update_stamp() {
  local -r package="$1" version="$2" download_file="$3"
  local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp"
  mkdir -p "$(dirname "$stamp")" && echo "$version" > "$stamp"
}

verify_stamp() {
  local verbose=false
  if [[ "$1" = "--verbose" ]]; then
    verbose=true
    shift
  fi
  local -r package="$1" version="$2" download_file="$3"
  local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp"
  local stamp_version
  if [[ -r "$stamp" ]]; then
    stamp_version="$(< "$stamp")"
  else
    stamp_version="missing"
  fi
  if [[ "$stamp_version" = "$version" ]]; then
    return 0
  fi
  if $verbose; then
    echo "WARNING: unpacked $package $stamp_version != current $version"
  fi
  return 1
}

list_package() {
  local -r package="$1" version="$2" download_file="$3" single_file="$4"
  local -r package_suffix="$5"
  local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp"
  local stamp_version
  if [[ -r "$stamp" ]]; then
    stamp_version="$(< "$stamp")"
  else
    stamp_version="missing"
  fi
  local installed="${stamp_version:-missing}"
  if [[ "$installed" = "$version" ]]; then
    installed="current"
  fi
  echo "$package$package_suffix" "installed=$installed" "current=$version"
}

verify_file() {
  local -r file="$1"
  local -r sum="$2"
  shasum --binary --check --status <<EOF
$sum *$file
EOF
}

download_package() {
  local -r package="$1" version="$2" download_file="$3" single_file="$4"
  local -r package_suffix="$5"
  local -r url="${URL_PREFIX}/${package}${package_suffix}/${version}"
  local -r download_file_with_dir="${DOWNLOAD_DIR}/${download_file}"

  # If the stamp file says it's already in place, do nothing more.
  verify_stamp "$package" "$version" "$download_file" && return

  rm -f -- "$download_file_with_dir"
  echo "Downloading $url"
  curl --progress-bar -continue-at=- --location \
       --create-dirs --output "$download_file_with_dir" "$url" || return

  verify_file "$download_file_with_dir" "$version" || {
    echo >&2 "*** VERIFICATION ERROR ***"
    echo >&2 "*** VERIFICATION ERROR *** $download_file from $url"
    echo >&2 "*** VERIFICATION ERROR *** Not using the file!"
    return 1
  }

  echo "Unpacking $download_file"
  if $single_file; then
    # The archive contains .cipd* metadata files and a single real file
    # whose name is the same as the basename of the package.
    unzip -q -o -d "$DOWNLOAD_DIR" "$download_file_with_dir" \
          "${package##*/}" || return
  else
    local -r dir="${download_file_with_dir%.zip}"
    rm -rf -- "$dir"
    unzip -q -d "$dir" "$download_file_with_dir" || return
  fi

  update_stamp "$package" "$version" "$download_file"
}

for_each_package() {
  local package version download_file single_file package_suffix status=0
  while read package version; do
    case "$package" in
    ''|\#*)
      continue
      ;;
    tools/*/${PLATFORM})
      # These are standalone executables contained in a .zip file.
      package="${package%/*}"
      download_file="${package#tools/}.zip"
      single_file=true
      package_suffix="/${PLATFORM}"
      ;;
    */${PLATFORM})
      package="${package%/*}"
      # Subdirectories are packed in .zip files.
      download_file="${package}.zip"
      single_file=false
      package_suffix="/${PLATFORM}"
      ;;
    firmware/*)
      # These are the same for every host platform.
      download_file="${package}.zip"
      single_file=false
      package_suffix=''
      ;;
    *)
      # Skip lines for other platforms.
      continue
      ;;
    esac
    "$@" "$package" "$version" "$download_file" $single_file "$package_suffix" ||
      status=$?
  done
  return $status
}

find_cipd() {
  # If the Zircon checkout is part of a jiri checkout that includes
  # //buildtools, then find cipd there.  Otherwise, if cipd is in
  # the PATH, take it from there.
  type -p "${ZIRCON_ROOT}/../buildtools/cipd" || type -p cipd
}

update_via_cipd() {
  local -r CIPD="$1"

  "$CIPD" ensure -ensure-file "${PREBUILTS_DIR}/zircon.ensure" \
                 -root "$DOWNLOAD_DIR" \
                 -log-level warning
  rc=$?
  if [[ $rc -ne 0 ]]; then
    echo >&2 "$0: $CIPD failed.  For direct downloads, remove cipd from PATH."
    return $rc
  fi

  "$(dirname $0)/update-prebuilt-versions" --verify || {
    echo >&2 "$0: update-prebuilt-versions not run after ensure file changed!"
    return 2
  }

  # Now update the .stamp files so that --verify will be happy.
  for_each_package update_stamp < "$VERSIONS_FILE"
}

write_sysroot_path() {
  local -r package="$1" version="$2"
  if [[ "$package" = sysroot ]]; then
    echo "SYSROOT_${PLATFORM}_PATH = \$(LKMAKEROOT)/prebuilt/downloads/sysroot"
  fi
}

write_config_mk() {
  local -r config_mk="${PREBUILTS_DIR}/config.mk"
  rm -f -- "$config_mk"
  echo > "$config_mk" "# Generated by $0.  DO NOT EDIT!"'

PREBUILT_CHECK := $(shell $(LKMAKEROOT)/scripts/download-prebuilt --verify)
ifneq (,$(strip $(PREBUILT_CHECK)))
$(warning)
$(warning $(PREBUILT_CHECK))
$(warning run scripts/download-prebuilt)
$(warning)
endif

ARCH_x86_64_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/gcc/bin/x86_64-elf-
ARCH_arm64_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/gcc/bin/aarch64-elf-
CLANG_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/clang/bin/
'

  for_each_package write_sysroot_path < "$VERSIONS_FILE" >> "$config_mk"
}

update() {
  local CIPD
  if $cipd_ok && CIPD="$(find_cipd)"; then
    # We have CIPD, so use it.
    update_via_cipd "$CIPD" || return
  else
    # We don't have CIPD, so don't use it.
    for_each_package download_package < "$VERSIONS_FILE" || return
  fi
  write_config_mk
}

verify() {
  for_each_package verify_stamp --verbose < "$VERSIONS_FILE"
}

list() {
  for_each_package list_package < "$VERSIONS_FILE"
}

$mode
