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

# Helper script that mounts chromium os image from a device or directory
# and creates mount points for /var and /usr/local (if in dev_mode).

# Helper scripts should be run from the same location as this script.
SCRIPT_ROOT=$(dirname "$(readlink -f "$0")")
. "${SCRIPT_ROOT}/common.sh" || exit 1

if [ $INSIDE_CHROOT -ne 1 ]; then
  INSTALL_ROOT="$SRC_ROOT/platform/installer/share"
else
  INSTALL_ROOT=/usr/share/misc
fi
# Load functions and constants for chromeos-install
. "${INSTALL_ROOT}/chromeos-common.sh" || exit 1

locate_gpt

# Flags.
DEFINE_string board "$DEFAULT_BOARD" \
  "The board for which the image was built." b
DEFINE_boolean read_only $FLAGS_FALSE \
  "Mount in read only mode -- skips stateful items."
DEFINE_boolean safe $FLAGS_FALSE \
  "Mount rootfs in read only mode."
DEFINE_boolean unmount $FLAGS_FALSE \
  "Unmount previously mounted dir." u
DEFINE_string from "/dev/sdc" \
  "Directory, image, or device with image on it" f
DEFINE_string image "chromiumos_image.bin"\
  "Name of the bin file if a directory is specified in the from flag" i
DEFINE_string "rootfs_mountpt" "/tmp/m" "Mount point for rootfs" "r"
DEFINE_string "stateful_mountpt" "/tmp/s" \
    "Mount point for stateful partition" "s"
DEFINE_string "esp_mountpt" "" \
    "Mount point for esp partition" "e"
DEFINE_boolean most_recent ${FLAGS_FALSE} "Use the most recent image dir" m

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

# Die on error
switch_to_strict_mode

# Find the last image built on the board.
if [ ${FLAGS_most_recent} -eq ${FLAGS_TRUE} ] ; then
  FLAGS_from="$(${SCRIPT_ROOT}/get_latest_image.sh --board="${FLAGS_board}")"
fi

# Check for conflicting args.
# If --from is a block device, --image can't also be specified.
if [ -b "${FLAGS_from}" ]; then
  if [ "${FLAGS_image}" != "chromiumos_image.bin" ]; then
    die_notrace "-i ${FLAGS_image} can't be used with block device ${FLAGS_from}"
  fi
fi

# Allow --from /foo/file.bin
if [ -f "${FLAGS_from}" ]; then
  # If --from is specified as a file, --image cannot be also specified.
  if [ "${FLAGS_image}" != "chromiumos_image.bin" ]; then
    die_notrace "-i ${FLAGS_image} can't be used with --from file ${FLAGS_from}"
  fi
  pathname=$(dirname "${FLAGS_from}")
  filename=$(basename "${FLAGS_from}")
  FLAGS_image="${filename}"
  FLAGS_from="${pathname}"
fi

# Common unmounts for either a device or directory
unmount_image() {
  info "Unmounting image from ${FLAGS_stateful_mountpt}" \
      "and ${FLAGS_rootfs_mountpt}"
  # Don't die on error to force cleanup
  set +e
  # Reset symlinks in /usr/local.
  if mount | egrep -q ".* ${FLAGS_stateful_mountpt} .*\(rw,"; then
    setup_symlinks_on_root "/usr/local" "/var" \
      "${FLAGS_stateful_mountpt}"
    fix_broken_symlinks "${FLAGS_rootfs_mountpt}"
  fi

  local m mnts=(
    "${FLAGS_esp_mountpt}"
    "${FLAGS_stateful_mountpt}"
    "${FLAGS_rootfs_mountpt}"
  )
  for m in "${mnts[@]}"; do
    if [[ -n ${m} ]]; then
      safe_umount_tree "${m}"
    fi
  done

  switch_to_strict_mode
}

get_usb_partitions() {
  local ro_flag=""
  local safe_flag=""
  [ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ] && ro_flag="-o ro"
  [ ${FLAGS_read_only} -eq ${FLAGS_TRUE} -o \
    ${FLAGS_safe} -eq ${FLAGS_TRUE} ] && safe_flag="-o ro -t ext2"

  sudo mount ${safe_flag} "${FLAGS_from}3" "${FLAGS_rootfs_mountpt}"
  sudo mount ${ro_flag} "${FLAGS_from}1" "${FLAGS_stateful_mountpt}"
  sudo mount ${ro_flag} "${FLAGS_from}8" "${FLAGS_rootfs_mountpt}/usr/share/oem"

  if [[ -n "${FLAGS_esp_mountpt}" && -e ${FLAGS_from}12 ]]; then
    sudo mount ${ro_flag} "${FLAGS_from}12" "${FLAGS_esp_mountpt}"
  fi
}

get_gpt_partitions() {
  local filename="${FLAGS_image}"

  # Mount the rootfs partition using a loopback device.
  local offset=$(partoffset "${FLAGS_from}/${filename}" 3)
  local ro_flag=""
  local safe_flag=""

  if [ ! -f "${FLAGS_from}/${filename}" ]; then
    die "Image ${FLAGS_from}/${filename} does not exist."
  fi

  if [ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ]; then
    ro_flag="-o ro"
  fi

  if [ ${FLAGS_read_only} -eq ${FLAGS_TRUE} -o \
       ${FLAGS_safe} -eq ${FLAGS_TRUE} ]; then
    safe_flag="-o ro -t ext2"
  else
    # Make sure any callers can actually mount and modify the fs
    # if desired.
    # cros_make_image_bootable should restore the bit if needed.
    enable_rw_mount "${FLAGS_from}/${filename}" "$(( offset * 512 ))"
  fi

  if ! sudo mount ${safe_flag} -o loop,offset=$(( offset * 512 )) \
      "${FLAGS_from}/${filename}" "${FLAGS_rootfs_mountpt}" ; then
    error "mount failed: options=${safe_flag} offset=$(( offset * 512 ))" \
        "target=${FLAGS_rootfs_mountpt}"
    return 1
  fi

  # Mount the stateful partition using a loopback device.
  offset=$(partoffset "${FLAGS_from}/${filename}" 1)
  if ! sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
      "${FLAGS_from}/${filename}" "${FLAGS_stateful_mountpt}" ; then
    error "mount failed: options=${ro_flag} offset=$(( offset * 512 ))" \
        "target=${FLAGS_stateful_mountpt}"
    return 1
  fi

  # Mount the oem partition using a loopback device.
  local oem_size=$(partsize "${FLAGS_from}/${filename}" 8)
  if [[ ${oem_size} -gt 0 ]]; then
    offset=$(partoffset "${FLAGS_from}/${filename}" 8)
    if ! sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
      "${FLAGS_from}/${filename}" "${FLAGS_rootfs_mountpt}/usr/share/oem" ; then
      error "mount failed: options=${safe_flag} offset=$(( offset * 512 ))" \
        "target=${FLAGS_rootfs_mountpt}/usr/share/oem"
      return 1
    fi
  fi

  # Mount the stateful partition using a loopback device.
  local esp_size
  if [[ -n "${FLAGS_esp_mountpt}" ]]; then
    esp_size=$(partsize "${FLAGS_from}/${filename}" 12)
    if [[ ${esp_size} -gt 0 ]]; then
      offset=$(partoffset "${FLAGS_from}/${filename}" 12)
      if ! sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
          "${FLAGS_from}/${filename}" "${FLAGS_esp_mountpt}" ; then
        error "mount failed: options=${ro_flag} offset=$(( offset * 512 ))" \
            "target=${FLAGS_esp_mountpt}"
        return 1
      fi
    fi
  fi
}

# Mount a gpt based image.
mount_image() {
  mkdir -p "${FLAGS_rootfs_mountpt}"
  mkdir -p "${FLAGS_stateful_mountpt}"
  if [[ -n "${FLAGS_esp_mountpt}" ]]; then
    mkdir -p "${FLAGS_esp_mountpt}"
  fi
  # Get the partitions for the image / device.
  if [ -b ${FLAGS_from} ] ; then
    get_usb_partitions
  elif ! get_gpt_partitions ; then
    echo "Current loopback device status:"
    sudo losetup --all | sed 's/^/    /'
    die "Failed to mount all partitions in ${FLAGS_from}/${FLAGS_image}"
  fi

  # Mount directories and setup symlinks.
  sudo mount --bind "${FLAGS_stateful_mountpt}" \
    "${FLAGS_rootfs_mountpt}/mnt/stateful_partition"
  sudo mount --bind "${FLAGS_stateful_mountpt}/var_overlay" \
    "${FLAGS_rootfs_mountpt}/var"
  sudo mount --bind "${FLAGS_stateful_mountpt}/dev_image" \
    "${FLAGS_rootfs_mountpt}/usr/local"

  # Setup symlinks in /usr/local so you can emerge packages into /usr/local.
  if [ ${FLAGS_read_only} -eq ${FLAGS_FALSE} ]; then
    setup_symlinks_on_root "${FLAGS_stateful_mountpt}/dev_image" \
      "${FLAGS_stateful_mountpt}/var_overlay" "${FLAGS_stateful_mountpt}"
  fi
  info "Image specified by ${FLAGS_from} mounted at"\
    "${FLAGS_rootfs_mountpt} successfully."
}

# Turn paths into absolute paths.
FLAGS_from=`eval readlink -f ${FLAGS_from}`
FLAGS_rootfs_mountpt=`eval readlink -f ${FLAGS_rootfs_mountpt}`
FLAGS_stateful_mountpt=`eval readlink -f ${FLAGS_stateful_mountpt}`

# Perform desired operation.
if [ ${FLAGS_unmount} -eq ${FLAGS_TRUE} ] ; then
  unmount_image
else
  mount_image
fi
