#!/bin/bash
# Copyright 2017 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.

# Loads script libraries.
CONTRIB_DIR=$(dirname "$(readlink -f "$0")")
. "${CONTRIB_DIR}/common.sh" || exit 1

FLAGS_HELP="
Command to rebuild firmware after a config change.

After you make a change to the firmware version in the master configuration,
run this script to test it. It will rebuild the master configuration, update
the Manifest and build the new firmware. You can then submit your CL to update
the master configuration, safe in the knowledge that you have tested it.

Usage:
   cros_update_firmware <board> [project]

where <board> is the board whose firmware needs updating (e.g. 'coral').
      [project] is the project the board belongs to.
"

# Flags
DEFINE_string board "${DEFAULT_BOARD}" "Which board the firmware is for" b
DEFINE_string project "${DEFAULT_PROJECT}" "Which project this board is for" p
DEFINE_boolean quiet "${FLAGS_FALSE}" "Reduce emerge build output" q
DEFINE_boolean append_srcuris "${FLAGS_TRUE}" "Only applicable when the project
flag is set. Append firmware uris to srcuris instead of overwriting. This is
usually needed if you have limited access to project config repos, so
overwriting would delete some uris."

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

# Script must be run inside the chroot.
assert_inside_chroot

start_workon() {
  local board="$1"
  local pkg item
  if [[ -z "$2" ]]; then
    echo "Empty package.  Skipping..."
    return 1
  fi
  pkg=$(cros workon --board="${board}" info "$2" | cut -d ' ' -f 1)
  shift 2
  for item in "$@"; do
    if [[ "${pkg}" == "${item}" ]]; then
      echo "Already workon ${pkg}.  Skipping..."
      return 1
    fi
  done
  cros workon --board="${board}" start "${pkg}"
  return $?
}

stop_workon() {
  cros workon --board="$1" stop "$2"
}

update_firmware() {
  local board="$1"
  local project="$2"
  local base ebuild srcuris cfg_bsp_pkg cfg_bsp_baseboard_pkg
  local current_workon_pkg_list start_pkg result i quiet
  [[ "$3" == "${FLAGS_TRUE}" ]] && quiet="--quiet-build"
  local append_srcuris="$4"

  set -e

  # query the current working package
  mapfile -t current_workon_pkg_list < <(cros workon --board="${board}" list)

  # check if chromeos-config-bsp is a virtual package
  cfg_bsp_pkg="chromeos-config-bsp"
  equery-"${board}" w chromeos-base/chromeos-config-bsp > /dev/null 2>&1 \
    || cfg_bsp_pkg="chromeos-config-bsp-${board}-private"
  # check if chromeos-config-bsp-baseboard is in use
  cfg_bsp_baseboard_pkg="chromeos-config-bsp-baseboard"
  equery-"${board}" w chromeos-base/chromeos-config-bsp-baseboard \
    > /dev/null 2>&1 || cfg_bsp_baseboard_pkg=

  start_pkg=("${cfg_bsp_pkg}")
  start_pkg+=("chromeos-firmware-${board}")
  start_pkg+=("${cfg_bsp_baseboard_pkg}")

  for i in "${!start_pkg[@]}"; do
    result[i]=0
    start_workon "${board}" "${start_pkg[i]}" "${current_workon_pkg_list[@]}" \
       || result[i]=$?
  done

  overlay="${GCLIENT_ROOT}/src/private-overlays/overlay-${board}-private"
  metadata="${overlay}/metadata"
  edb_cache="/var/cache/edb/dep/mnt/host/source/src/private-overlays/overlay-${board}-private"
  base="${overlay}/chromeos-base"
  ebuild="${base}/chromeos-firmware-${board}/chromeos-firmware-${board}-9999.ebuild"
  srcuris="${base}/chromeos-firmware-${board}/files/srcuris"
  yaml_config="/build/${board}/usr/share/chromeos-config/yaml/config.yaml"

  # Check project config repo exists -- if so generate the config first.
  if [[ -d "${GCLIENT_ROOT}/src/project/${project}" ]]; then
    pushd "${GCLIENT_ROOT}/src/project/${project}" > /dev/null
    for brd in *; do
      if [[ -d "${brd}" && -x "${brd}/config/bin/gen_config" && -f "${brd}/config.star" ]]; then
        pushd "${brd}" > /dev/null
        ./config/bin/gen_config config.star
        popd > /dev/null
      fi
    done
    popd > /dev/null
  fi

  "emerge-${board}" -j ${quiet} ${cfg_bsp_baseboard_pkg} "${cfg_bsp_pkg}" chromeos-config

  # If the append_srcuris and project flags are set, append uris that aren't
  # already in srcuris. Otherwise, overwrite srcuris.
  if [[ -n "${project}" && "${append_srcuris}" == "${FLAGS_TRUE}" ]]; then
    for uri in $(cros_config_host -c "${yaml_config}" get-firmware-uris); do
      if ! grep -q "${uri}" "${srcuris}"; then
        # Append uri to the last line of srcuris (srcuris should be a file with
        # a single line). Escape slashes in uri.
        sed -i "$ s/$/ ${uri//\//\\/}/" "${srcuris}"
      fi
    done
  else
    cros_config_host -c "${yaml_config}" get-firmware-uris > "${srcuris}"
  fi

  touch "${ebuild}"

  # Clean metadata cache to make sure SRC_URI is fetched from ${srcuris}
  # instead from portage cache which maybe out of sync.
  # Note: this workaround is needed because we break the SRC_URI API contract
  # which is supposed to be a static (see
  # https://devmanual.gentoo.org/general-concepts/portage-cache/index.html).
  # TODO(crbug.com/927917): find a different way to generate SRC_URI and remove
  # these cache cleanup code.
  rm -rf "${metadata}/cache" "${metadata}/md5-cache" "${edb_cache}"
  "ebuild-${board}" "${ebuild}" manifest
  "emerge-${board}" -j ${quiet} "chromeos-firmware-${board}"

  for i in "${!result[@]}"; do
    if [[ "${result[i]}" -eq "0" ]]; then
      stop_workon "${board}" "${start_pkg[i]}"
    fi
  done
}

main() {
  if [[ -z "${FLAGS_board}" ]]; then
    die "-b or --board required."
  fi

  update_firmware "${FLAGS_board}" "${FLAGS_project}" "${FLAGS_quiet}" "${FLAGS_append_srcuris}"
}

main "$@"
