#!/bin/bash

# Copyright (c) 2011 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.

# This script moves ebuilds between 'stable' and 'live' states.
# By default 'stable' ebuilds point at and build from source at the
# last known good commit. Moving an ebuild to 'live' (via cros_workon start)
# is intended to support development. The current source tip is fetched,
# source modified and built using the unstable 'live' (9999) ebuild.

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

assert_not_root_user

# Script must be run inside the chroot

DEFINE_string board "${DEFAULT_BOARD}" \
  "The board to set package keywords for."
DEFINE_string brick "" \
  "The brick to set package keywords for."
DEFINE_boolean host "${FLAGS_FALSE}" \
  "Uses the host instead of board"
DEFINE_string remote "" \
  "For non-workon projects, the git remote to use."
DEFINE_string revision "" \
  "Use to override the manifest defined default revision used for a project"
DEFINE_string command "git status" \
  "The command to be run by forall."
DEFINE_boolean all "${FLAGS_FALSE}" \
  "Apply to all possible packages for the given command"

FLAGS_HELP="usage: $0 <command> [flags] [<list of packages>|.|--all]
commands:
  start:     Moves an ebuild to live (intended to support development)
  stop:      Moves an ebuild to stable (use last known good)
  info:      Print package name, repo name, and source directory.
  list:      List of live ebuilds (workon ebuilds if --all)
  list-all:  List all of the live ebuilds for all setup boards
  iterate:   For each ebuild, cd to the source dir and run a command"
FLAGS "$@" || { [ "${FLAGS_help}" = "${FLAGS_TRUE}" ]  && exit 0; } || exit 1
eval set -- "${FLAGS_ARGV}"


# eat the workon command keywords: start, stop or list.
WORKON_CMD=$1
shift

# Board dir config

# --host takes precedence over --{brick,board}; --brick takes precedence over
# --board. This preserves prior behavior meant to accommodate default values.
if [[ "${FLAGS_host}" == ${FLAGS_TRUE} ]]; then
  if [[ -n "${FLAGS_board}" ]] || [[ -n "${FLAGS_brick}" ]]; then
    warn "--host was used, ignoring --brick and --board values"
    FLAGS_brick=""
    FLAGS_board=""
  fi
elif [[ -n "${FLAGS_brick}" ]]; then
  # Override board name with the brick's friendly name (backward compatibility).
  [[ -z "${FLAGS_board}" ]] || warn "--brick was used, ignoring --board value"
  FLAGS_board="$(cros_brick_utils --friendly-name "${FLAGS_brick}")"
  [[ -n "${FLAGS_board}" ]] || die_notrace
fi

if [ -z "${FLAGS_board}" ] && \
   [ "${FLAGS_host}" = ${FLAGS_FALSE} ] && \
   [ "${WORKON_CMD}" != "list-all" ]; then
  flags_help
  die "You must specify either --host, --board or --brick"
fi

if [ -n "${FLAGS_board}" ]; then
  BOARD_DIR=/build/"${FLAGS_board}" # --board specified
  EQUERYCMD=equery-"${FLAGS_board}"
  EBUILDCMD=ebuild-"${FLAGS_board}"
  PORTAGEQCMD=portageq-"${FLAGS_board}"
  BOARD_STR="${FLAGS_board}"
else
  BOARD_DIR="" # --host specified
  EQUERYCMD=equery
  EBUILDCMD=ebuild
  PORTAGEQCMD=portageq
  BOARD_STR="host"
fi

WORKON_DIR="${CHROOT_TRUNK_DIR}/.config/cros_workon"
CONFIG_DIR="${BOARD_DIR}/etc/portage"
KEYWORDS_DIR="${CONFIG_DIR}/package.keywords"
MASK_DIR="${CONFIG_DIR}/package.mask"
UNMASK_DIR="${CONFIG_DIR}/package.unmask"
WORKON_FILE="${WORKON_DIR}/${BOARD_STR}"
MASK_WORKON_FILE="${WORKON_FILE}.mask"
KEYWORDS_FILE="${KEYWORDS_DIR}/cros-workon"
MASK_FILE="${MASK_DIR}/cros-workon"
UNMASK_FILE="${UNMASK_DIR}/cros-workon"
CHROME_ATOM=chromeos-base/chromeos-chrome

mkdir -p "${WORKON_DIR}" || die "mkdir -p ${WORKON_DIR}"
touch "${WORKON_FILE}" "${MASK_WORKON_FILE}" || \
  die "touch ${WORKON_FILE} ${MASK_WORKON_FILE}"
cmds=(
  "mkdir -p '${KEYWORDS_DIR}' '${MASK_DIR}' '${UNMASK_DIR}'"

  # Clobber and re-create the WORKON_FILE symlinks every time. This
  # is a trivial operation and eliminates all kinds of corner cases
  # as well as any possible future renames of WORKON_FILE.
  # In particular, chroot is usually built as "amd64-host" but becomes
  # just "host" after installation. crosbug.com/23096
  "ln -sf '${WORKON_FILE}' '${KEYWORDS_FILE}'"
  "ln -sf '${MASK_WORKON_FILE}' '${MASK_FILE}'"
  "ln -sf '${WORKON_FILE}' '${UNMASK_FILE}'"
)
# If the board dir doesn't exist yet, we don't want to create it as
# that'll screw up ./setup_board later on.
if [[ -d ${BOARD_DIR:-/} ]] ; then
  sudo_multi "${cmds[@]}"
else
  die "${BOARD_STR} has not been setup yet"
fi


find_keyword_workon_ebuilds() {
  local keyword="${1}"
  local overlay

  # NOTE: overlay may be a symlink, and we have to use ${overlay}/
  for overlay in "${OVERLAYS[@]}"; do
    # only look up ebuilds named 9999 to eliminate duplicates
    find "${overlay}"/*-* -maxdepth 2 -type f -name '*9999.ebuild' \
      -exec grep -l 'inherit.*cros-workon' {} + 2>/dev/null | \
      xargs egrep -l "KEYWORDS=\".*~([*]|${keyword})[ \"]"
  done
}

ebuild_to_package() {
  # This changes the absolute path to ebuilds into category/package.
  sed -e 's/.*\/\([^/]*\)\/\([^/]*\)\/.*\.ebuild/\1\/\2/'
}

show_project_ebuild_map() {
  local keyword="$1"
  local project_var

  # Column 1: Repo name
  # Column 2: Package name
  for EBUILD in $(find_keyword_workon_ebuilds ${keyword}); do
    (
      project_var=$(awk -- \
        '/CROS_WORKON_PROJECT=/,/CROS_WORKON_PROJECT=[^(]|\)/' "${EBUILD}")
      # Can only detect syntax errors in subshells; not in our own.
      if ( eval "${project_var}" ); then
        eval "${project_var}"
      else
        error "From $EBUILD, failed to eval:"
        error "$project_var"
        continue
      fi
      CP=$(echo "$EBUILD" | ebuild_to_package)
      projects=$(echo "${CROS_WORKON_PROJECT[@]}" | sed 's/ /,/g')
      echo "${projects:--}" "${CP}"
    )
  done
}

show_project_path_map() {
  # Column 1: Repo name
  # Column 2: Source directory
  repo list | awk -F ' : ' '{ print $2, $1 }'
}

show_workon_ebuilds() {
  local keyword="$1"
  find_keyword_workon_ebuilds "${keyword}" | ebuild_to_package | sort -u
}

show_workon_info() {
   local atoms="$1"
   local keyword="$2"
   local sort="sort -k1b,1"
   # Column 1: Package name
   # Column 2: Repo name
   # Column 3: Source directory (if present locally)
   join \
     <(echo "${atoms}" | sed -e 's/ /\n/g' | ${sort}) \
     <(join -a 1 -e - -o 1.2,1.1,2.2 \
       <(show_project_ebuild_map "${keyword}" | ${sort}) \
       <(show_project_path_map | ${sort}) \
       | ${sort})
}

# Canonicalize package name to category/package.
canonicalize_name() {
  local pkgfile
  local pkgname

  if grep -qx "=$1-9999" "${WORKON_FILE}" ; then
    echo $1
    return 0
  fi

  if ! pkgfile=$(ACCEPT_KEYWORDS="~${ARCH}" ${EQUERYCMD} \
                 which --include-masked $1); then
    # Try to auto-complete it.
    local autopkgs=()
    for pkgname in $(show_workon_ebuilds); do
      if [[ ${pkgname} == *"$1"* ]]; then
        autopkgs+=( ${pkgname} )
      fi
    done
    case ${#autopkgs[@]} in
    0)
      warn "error looking up package $1" 1>&2
      return 1
      ;;
    1)
      # Do nothing -- fall through.
      ;;
    *)
      warn "Multiple autocompletes found: ${autopkgs[*]}"
      ;;
    esac
    pkgname=${autopkgs[0]}
    info "Autocompleted '$1' to: ${pkgname}"
    canonicalize_name "${pkgname}"
    return
  fi

  pkgname=$(echo "${pkgfile}" | awk -F '/' '{ print $(NF-2) "/" $(NF-1) }')

  # TODO(rcui): remove special casing of chromeos-chrome here when we make it
  # inherit from cros-workon class.  Tracked in chromium-os:19259.
  if [ "${pkgname}" != "${CHROME_ATOM}" ] && \
     ! grep -q "cros-workon" ${pkgfile}; then
    warn "${pkgname} is not a cros-workon package" 1>&2
    return 1
  fi
  echo "${pkgname}"
  return 0
}

# Canonicalize a list of names.
canonicalize_names() {
  local atoms=$1
  local names=()
  local atom

  for atom in ${atoms}; do
    names+=( $(canonicalize_name "${atom}") ) || return 1
  done

  echo "${names[*]}"
}

# Locate the package name based on the current directory
locate_package() {
  local projectname=$(git config --get remote.cros.projectname ||
                      git config --get remote.cros-internal.projectname)
  if [ -z "${projectname}" ]; then
    die "No project in git config: Can not cros_workon . here"
  fi
  local reponame=$(show_project_ebuild_map |
                   grep "^${projectname} " | cut -d" " -f2)
  if [ -z "${reponame}" ]; then
    die "No matching package for ${projectname}: Can not cros_workon . here"
  else
    echo "${reponame}"
  fi
}

# Display ebuilds currently part of the live branch and open for development.
show_live_ebuilds() {
  sed -n 's/^=\(.*\)-9999$/\1/p' "${WORKON_FILE}"
}

# Display ebuilds currently part of the live branch and open for development
# for any board that currently has live ebuilds.
show_all_live_ebuilds() {
  local workon_file
  for workon_file in ${WORKON_DIR}/*; do
    if [[ -s ${workon_file} && ${workon_file} != *.mask ]] ; then
      echo -e "${V_BOLD_GREEN}$(basename ${workon_file}):${V_VIDOFF}"
      sed -n 's/^=\(.*\)-9999$/    \1/p' "${workon_file}"
      echo ""
    fi
  done
}

# This is called only for "cros-workon start". We dont handle the
# "stop" case since the local changes are ignored anyway since the
# 9999.ebuild is masked and we dont want to deal with what to do with
# the user's local changes.
regen_manifest_and_sync() {
  # Nothing to do unless you are working on the minilayout
  local manifest=${CHROOT_TRUNK_DIR}/.repo/manifest.xml
  if [ $(basename $(readlink -f ${manifest})) != "minilayout.xml" ]; then
    if [ -z "$(git config -f "${CHROOT_TRUNK_DIR}/.repo/manifests.git/config" \
               --get manifest.groups)" ]; then
      # Reaching here means that it's a full manifest w/out any groups set-
      # literal full manifest.
      return
    fi
  fi

  local need_repo_sync=
  local pkgname
  for pkgname in $(show_live_ebuilds); do
    local pkgpath="$(${EQUERYCMD} which "${pkgname}")"
    local pkginfo="$(${EBUILDCMD} "${pkgpath}" info |
                   grep -v 'pkg_info() is not defined')"
    if [ -z "${pkginfo}" ]; then
      continue  # No package information available
    fi

    eval "${pkginfo}"
    local trunkdir=$(readlink -m "${CHROOT_TRUNK_DIR}")

    local i
    for (( i=0; i < ${#CROS_WORKON_SRCDIR[@]}; ++i )); do
      [ -z "${CROS_WORKON_PROJECT[i]}" ] && continue
      need_repo_sync='yes'
      local srcdir=$(readlink -m "${CROS_WORKON_SRCDIR[i]}")
      local revision="${FLAGS_revision:+--revision=${FLAGS_revision}}"
      if [ -z "${FLAGS_remote}" ]; then
        loman add --workon "${CROS_WORKON_PROJECT[i]}" ${revision}
      else
        loman add --remote "${FLAGS_remote}" ${revision} \
          "${CROS_WORKON_PROJECT[i]}" "${srcdir#${trunkdir}/}"
      fi
    done
  done
  if [ -n "${need_repo_sync}" ]; then
    echo "Please run \"repo sync\" now."
  fi
}

# Move a stable ebuild to the live development catgeory.  The ebuild
# src_unpack step fetches the package source for local development.
ebuild_to_live() {
  local atoms=$1
  local atoms_success=()
  local atom

  for atom in ${atoms}; do
    if ! grep -qx "=${atom}-9999" "${WORKON_FILE}" ; then
      echo "=${atom}-9999" >> "${WORKON_FILE}" || \
        die "Could not update ${WORKON_FILE} with ${atom}"
      echo "<${atom}-9999" >> "${MASK_WORKON_FILE}" || \
        die "Could not update ${MASK_WORKON_FILE} with ${atom}"
      atoms_success+=( ${atom} )
    else
      warn "Already working on ${atom}"
    fi
  done
  [ ${#atoms_success[@]} -gt 0 ] && regen_manifest_and_sync && \
    info "Started working on '${atoms_success[*]}' for '${BOARD_STR}'"
}

# Move a live development ebuild back to stable.
ebuild_to_stable() {
  local atoms=$1
  local atoms_success=()
  local atom

  for atom in ${atoms}; do
    if grep -qx "=${atom}-9999" "${WORKON_FILE}" "${MASK_WORKON_FILE}" ; then
      sed -i -e "/^=${atom/\//\\/}-9999\$/d" "${WORKON_FILE}" || \
        die "Could not update ${WORKON_FILE} with ${atom}"
      sed -i -e "/^<${atom/\//\\/}-9999\$/d" "${MASK_WORKON_FILE}" || \
        die "Could not update ${WORKON_FILE} with ${atom}"
      atoms_success+=( ${atom} )
    else
      warn "Not working on ${atom}"
    fi
  done
  [ ${#atoms_success[@]} -gt 0 ] && \
    info "Stopped working on '${atoms_success[*]}' for '${BOARD_STR}'"
}

# Run a command on all or a set of repos.
ebuild_iterate() {
  local atoms=$1
  local atom

  for atom in ${atoms}; do
    info "Running \"${FLAGS_command}\" on ${atom}"
    eval $(${EBUILDCMD} $(${EQUERYCMD} which ${atom}) info)
    for S in "${CROS_WORKON_SRCDIR[@]}"; do
      (cd "${S}" && bash -c "${FLAGS_command}")
    done
  done
}

# Only call portageq when absolutely required, and when we do, only run it
# once -- it's a slow beast and can easily take hundreds of milliseconds :(.
if [[ ${WORKON_CMD} != "list" || ${FLAGS_all} != ${FLAGS_FALSE} ]] ; then
  ARCH=$(${PORTAGEQCMD} envvar ARCH)
  cmd=( cros_list_overlays )
  if [[ -n "${FLAGS_brick}" ]]; then
    cmd+=( --brick "${FLAGS_brick}" )
  else
    cmd+=( --all )
    if [[ -n "${FLAGS_board}" ]]; then
      cmd+=( --board "${FLAGS_board}" )
    fi
  fi
  OVERLAYS=( $("${cmd[@]}") )
fi

# --all makes commands operate on different lists
if [ ${FLAGS_all} = "${FLAGS_TRUE}" ]; then
  case ${WORKON_CMD} in
    start|info) ATOM_LIST=$(show_workon_ebuilds ${ARCH});;
    stop|iterate) ATOM_LIST=$(show_live_ebuilds);;
    list) ;;
    *) die "--all is invalid for the given command";;
  esac
else # not selected --all
  case ${WORKON_CMD} in
    start|stop|info|iterate)
      ATOM_LIST=$@
      if [ -z "${ATOM_LIST}" ]; then
        die "${WORKON_CMD}: No packages specified"
      fi
      if [ "${ATOM_LIST}" = "." ]; then
        ATOM_LIST=$(locate_package)
      fi
      if ! ATOM_LIST=$(canonicalize_names "${ATOM_LIST}"); then
        die "Error parsing package list"
      fi;;
    *) ;;
  esac
fi

case ${WORKON_CMD} in
  start) ebuild_to_live "${ATOM_LIST}" ;;
  stop) ebuild_to_stable "${ATOM_LIST}" ;;
  info) show_workon_info "${ATOM_LIST}" "${ARCH}" ;;
  list) [ ${FLAGS_all} = "${FLAGS_FALSE}" ] && show_live_ebuilds || \
    show_workon_ebuilds ${ARCH} ;;
  list-all) show_all_live_ebuilds ;;
  iterate) ebuild_iterate "${ATOM_LIST}" ;;
  *)
    flags_help
    die "$(basename $0): command '${WORKON_CMD}' not recognized"
    ;;
esac
