#!/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.

set -o pipefail

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" internal_access="$2"

  local -a ensure_files=("${PREBUILTS_DIR}/zircon.ensure")
  if $internal_access; then
    ensure_files+=("${PREBUILTS_DIR}/zircon_internal.ensure")
  fi

  (sed '/^\$/!d' "${ensure_files[@]}" && sed '/^\$/d' "${ensure_files[@]}") |
    "$CIPD" ensure -ensure-file - -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 internal_access="$1"
  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"

  echo >> "$config_mk" "INTERNAL_ACCESS := ${internal_access}"
}

update() {
  local CIPD
  local internal_access=false
  if $cipd_ok && CIPD="$(find_cipd)"; then
    # We have CIPD, so use it.
    if [[ "$("$CIPD" ls fuchsia_internal)" != "No matching packages." ]]; then
      internal_access=true
    fi
    update_via_cipd "$CIPD" "$internal_access" || return
  else
    # We don't have CIPD, so don't use it.
    for_each_package download_package < "$VERSIONS_FILE" || return
  fi
  write_config_mk "$internal_access"
}

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

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

$mode
