#!/bin/bash

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

. "$(dirname "$0")/common.sh" || exit 1

# Script must run inside the chroot
restart_in_chroot_if_needed "$@"

assert_not_root_user

# Developer-visible flags.
DEFINE_boolean configure $FLAGS_TRUE \
  "Update config files in <sysroot>/etc after installation."
DEFINE_boolean force $FLAGS_FALSE \
  "Install toolchain even if already up to date."
DEFINE_string toolchain "" \
  "Toolchain.  For example: i686-pc-linux-gnu, armv7a-softfloat-linux-gnueabi"
DEFINE_string sysroot "" "The sysroot to install the toolchain for."


FLAGS_HELP="usage: $(basename $0) [flags]

Installs cross toolchain libraries into a sysroot.  This script is not
meant to be used by developers directly.  Run at your own risk.
"

show_help_if_requested "$@"

# Parse command line flags
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"

# Only now can we die on error.  shflags functions leak non-zero error codes,
# so will die prematurely if 'switch_to_strict_mode' is specified before now.
switch_to_strict_mode

# Get the version number of a toolchain package.
cross_get_version() {
  local pkg=$1
  local toolchain=${2:-${FLAGS_toolchain}}
  local cpv
  if [[ "${CHOST}" != "${toolchain}" ]]; then
    cpv=$(portageq match / "cross-${toolchain}/${pkg}" || true)
  else
    if [[ "${pkg}" == glibc ]] ; then
      cpv=$(portageq match / sys-libs/glibc || true)
    elif [[ "${pkg}" == gcc ]] ; then
      cpv=$(portageq match / sys-devel/gcc || true)
    elif [[ "${pkg}" == go ]] ; then
      cpv=$(portageq match / dev-lang/go || true)
    else
      die "Unknown pkg ${pkg}"
    fi
  fi
  local cp=$(echo ${cpv} | sed -e 's/-r[0-9]*$//; s/-[^-]*$//')
  local result="${cpv#$cp-}"
  local count="$(echo $result | wc -w)"
  if [ "${count}" -gt "1" ]; then
    die "Multiple versions of ${pkg} installed"
  fi
  echo "${result}"
}

# Get the version number of a toolchain package.
# Die if the package is not found.
cross_get_version_or_die() {
  local pkg=$1
  local result=$(cross_get_version "$@")
  local count="$(echo $result | wc -w)"
  if [ "${count}" -lt "1" ]; then
    die "Cannot find ${pkg}"
  fi
  echo "${result}"
}

# Checks whether the libc version installed in the board
# matches the one installed by the toolchain.
board_needs_libc_update() {
  local board_version=$(get_variable "${SYSROOT_CACHE}" "LIBC_VERSION")
  local toolchain_version
  # Keep `local` decl split from assignment so return code is checked.
  toolchain_version=$(cross_get_version_or_die glibc)
  if [[ "${board_version}" = "${toolchain_version}" ]]; then
    return 1
  fi
  return 0
}

install_toolchain_in_provided() {
  local gcc_ver="$1"
  local glibc_ver="$2"
  local go_ver="$3"
  # Tell portage that toolchain packages are already installed in the sysroot.
  sudo mkdir -p "$BOARD_PROFILE"
  sudo_clobber "$BOARD_PROFILE/package.provided" << EOF
sys-devel/gcc-$gcc_ver
sys-libs/glibc-$glibc_ver
EOF
  if [[ -n ${go_ver} ]]; then
    sudo_append "$BOARD_PROFILE/package.provided" << EOF
dev-lang/go-${go_ver}
EOF
  fi
}

# Install all of the stuff that depends on the toolchain versions
# into the board root.
install_toolchain_in_board() {
  local cmds gcc_ver libc_ver go_ver
  # Keep `local` decl split from assignments so return code is checked.
  gcc_ver=$(cross_get_version_or_die gcc)
  libc_ver=$(cross_get_version_or_die glibc)
  go_ver=$(cross_get_version go)
  if [[ -z ${gcc_ver} || -z ${libc_ver} ]]; then
    die "Cannot find toolchain to install into board root"
  fi
  info "Installing the toolchain into the board root."
  # Untar glibc to get most of the headers required to build.

  # Install libc libraries.
  if [ "${CHOST}" != "$FLAGS_toolchain" ] ; then
    local libc_atom="cross-${FLAGS_toolchain}/glibc-${libc_ver}"
    local libc_path="${PKGDIR}/${libc_atom}.tbz2"

    cmds=()
    if [[ ! -e ${libc_path} ]]; then
        cmds+=( "emerge --nodeps -gf =${libc_atom}" )
    fi
    cmds+=(
      "tar jxpf '${libc_path}' -C '${BOARD_ROOT}' \
          './usr/${FLAGS_toolchain}' --strip-components=3"
      "mkdir -p '${BOARD_ROOT}/usr/lib/debug'"
      "tar jxpf '${libc_path}' -C '${BOARD_ROOT}/usr/lib/debug' \
          './usr/lib/debug/usr/${FLAGS_toolchain}' --strip-components=6 \
          || echo 'WARNING: libc debug info not copied.' >&2"
    )
    sudo_multi "${cmds[@]}"
  else
    sudo emerge --oneshot --nodeps -k --root='${BOARD_ROOT}' \
      =sys-libs/glibc-${libc_ver}
  fi

  if [[ ${FLAGS_configure} -eq ${FLAGS_TRUE} ]]; then
    install_toolchain_in_provided "$gcc_ver" "$libc_ver" "$go_ver"

    set_variable "${SYSROOT_CACHE}" "LIBC_VERSION" "${libc_ver}"
  fi
}

set -u

if [[ -z "${FLAGS_sysroot}" ]]; then
  die "--sysroot required."
fi

BOARD_ROOT="${FLAGS_sysroot}"
BOARD_ETC="${BOARD_ROOT}/etc"
BOARD_PROFILE="${BOARD_ETC}/portage/profile"
SYSROOT_CACHE="${BOARD_ROOT}/${SYSROOT_SETTINGS_FILE}"

sysroot_toolchain="$(get_sysroot_config "${FLAGS_sysroot}" "CHOST")"
: ${FLAGS_toolchain:=${sysroot_toolchain}}

if [ -z "${FLAGS_toolchain}" ]; then
  die "No toolchain specified in the sysroot or on command line."
fi

eval "$(portageq envvar -v CHOST PKGDIR)"

if [[ ${FLAGS_force} -eq ${FLAGS_TRUE} ]] || \
    board_needs_libc_update; then
  info "Updating libc in the board."
  install_toolchain_in_board
else
  info "Cross toolchain already up to date.  Nothing to do."
fi
