#!/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
. "${SRC_ROOT}/platform/dev/toolchain_utils.sh" || exit 1

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

assert_not_root_user

# Developer-visible flags.
DEFINE_string board "$DEFAULT_BOARD" \
  "The name of the board to set up."
DEFINE_string board_root "" \
  "Path of the board root to install into.  Defaults to /build/<board>."
DEFINE_boolean configure $FLAGS_TRUE \
  "Update config files in <board_root>/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"


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

Installs cross toolchain libraries into a board_root.  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
    if [[  "$pkg" = "gcc" ]]; then
      # Users can install multiple versions of gcc at once, so we need to call
      # gcc-config to find out which installed version is selected.
      local path=$(CTARGET="${toolchain}" gcc-config -B || true)
      cpv=$(portageq owners / "$path" | sed -e '/^\t/d')
    else
      cpv=$(portageq match / "cross-${toolchain}/${pkg}" || true)
    fi
  else
    if [[ "$pkg" = glibc ]] ; then
      cpv=$(portageq match / sys-libs/glibc || true)
    elif [[ "$pkg" = gcc ]] ; then
      cpv=$(portageq match / sys-devel/gcc || 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"
  elif [ "$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() {
  if [[ ! -e "${BOARD_SETUP}" ]]; then
    return 0
  fi

  local board_version=$(. "${BOARD_SETUP}"; echo "${LIBC_VERSION}")
  local toolchain_version=$(cross_get_version glibc)
  if [[ "${board_version}" = "${toolchain_version}" ]]; then
    return 1
  fi
  return 0
}

install_toolchain_in_provided() {
  local gcc_ver="$1"
  local glibc_ver="$2"
  # Tell portage that toolchain packages are already installed in the sysroot.
  sudo_clobber "$BOARD_PROFILE/package.provided" << EOF
sys-devel/gcc-$gcc_ver
sys-libs/glibc-$glibc_ver
EOF
}

# Install all of the stuff that depends on the toolchain versions
# into the board root.
install_toolchain_in_board() {
  local cmds
  local gcc_ver=$(cross_get_version gcc)
  local libc_ver=$(cross_get_version glibc)
  if [[ -z ${gcc_ver} || -z ${libc_ver} ]]; then
    die "Cannot find toolchain to install into board root"
  fi
  echo "Installing the toolchain into the board root."
  # Untar glibc to get most of the headers required to build.
  local libc_tar="glibc-${libc_ver}.tbz2"

  # Install libc libraries.
  if [ "${CHOST}" != "$FLAGS_toolchain" ] ; then
    local libc_path="${PKGDIR}/cross-${FLAGS_toolchain}/${libc_tar}"
    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 \
          || warn 'libc debug info not copied.'"
    )
    # TODO(asharif): Remove this hack after a while.
    local board_gcc_dir="${BOARD_ROOT}/usr/lib/gcc"
    if [[ -L "${board_gcc_dir}" ]] ; then
      cmd+=("rm -f '${board_gcc_dir}'")
    fi
    sudo_multi "${cmds[@]}"
    copy_gcc_libs "${BOARD_ROOT}" "cross-$FLAGS_toolchain/gcc-$gcc_ver"
  else
    cmds=(
      "mkdir -p '${BOARD_ROOT}'{/usr,}/lib64 '${BOARD_ROOT}/usr/lib/debug'"
      "ln -sfT '${BOARD_ROOT}/usr/lib64' '${BOARD_ROOT}/usr/lib'"
      "ln -sfT '${BOARD_ROOT}/lib64' '${BOARD_ROOT}/lib'"
      "emerge --oneshot --nodeps -k --root='${BOARD_ROOT}' \
          =sys-libs/glibc-${libc_ver}"
    )
    sudo_multi "${cmds[@]}"
  fi

  # Some header files are needed also for rpcbind (NFS support)
  # TODO: Figure out a better way of doing this too?
  cmds=(
    "cp -a /usr/include/rpcsvc/mount.h '${BOARD_ROOT}/usr/include/rpcsvc'"
    "cp -a /usr/include/rpcsvc/rquota.h '${BOARD_ROOT}/usr/include/rpcsvc'"
    "cp -a /usr/include/rpcsvc/nfs_prot.h '${BOARD_ROOT}/usr/include/rpcsvc'"
    "cp -a /usr/include/rpcsvc/yppasswd.h '${BOARD_ROOT}/usr/include/rpcsvc'"
  )
  sudo_multi "${cmds[@]}"

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

    # Configure new libc version in make.conf.board_setup.
    sudo sed -i -e "/^LIBC_VERSION=/d" "$BOARD_SETUP"
    echo "LIBC_VERSION=\"$libc_ver\"" | sudo_append "$BOARD_SETUP"
  fi
}

set -u

if [ -z "$FLAGS_board" ] ; then
  die "--board required."
fi

get_board_and_variant $FLAGS_board ""

BOARD_ROOT="${FLAGS_board_root:-/build/${BOARD_VARIANT}}"
BOARD_ETC="${BOARD_ROOT}/etc"
BOARD_SETUP="${BOARD_ETC}/make.conf.board_setup"
BOARD_PROFILE="${BOARD_ETC}/portage/profile"

all_toolchains=( $(get_all_board_toolchains "${BOARD}") )
: ${FLAGS_toolchain:=${all_toolchains[0]}}

if [ -z "${FLAGS_toolchain}" ]; then
  die "No toolchain specified in board overlay 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
