#!/bin/bash

function mk_build_dir () {
  TMP_BUILD_DIR=$(mktemp -t -d --tmpdir=${TMP_DIR:-/tmp} hmi_build.XXXXXXXX) 
  [ $? -eq 0 ] || die "Failed to create tmp directory"

  export TMP_BUILD_DIR
  trap trap_cleanup EXIT
  echo Building in $TMP_BUILD_DIR
  export TMP_MOUNT_PATH=$TMP_BUILD_DIR/mnt
  export TMP_HOOKS_PATH=$TMP_BUILD_DIR/hooks
}

function finish_image () {
    if [ -f $1 -a ${OVERWRITE_OLD_IMAGE:-0} -eq 0 ]; then
        old_image="${1%.*}"-$(date +%Y.%m.%d-%H.%M.%S).${1##*.}
        echo "Old image found. Renaming it to $old_image"
        mv "$1" "$old_image"  
        if [ -f "$1.md5" ]; then
            mv "$1.md5" "$old_image.md5"
        fi
        if [ -f "$1.sha256" ]; then
            mv "$1.sha256" "$old_image.sha256"
        fi
    fi

    mv $OUT_IMAGE_PATH $1
    if [ "$DIB_CHECKSUM" == "1" ]; then
        md5sum $1 > $1.md5
        sha256sum $1 > $1.sha256
    fi
    echo "Image file $1 created..."
}

function save_image () {
     inish_image $1
}

function generate_hooks () {
    mkdir -p $TMP_HOOKS_PATH
    cp -a $_PREFIX/hooks/* $TMP_HOOKS_PATH/
}

# Call the supplied break-in routine if the named point is listed in the break
# list.
# $1 the break point.
# $2.. what to call if a break is needed
function check_break () {
    if echo "${break:-}" | egrep -e "(,|^)$1(,|$)" -q; then
        echo "Starting debug shell. Exit to resume building." >&2
        echo At stage $1 >&2
        shift
        "$@"
        echo "Resuming" >&2
    fi
}

# Check that a real hooks has been chosen (prevents foot-guns)
function check_hooks () {
    [ -d $TMP_HOOKS_PATH ] || generate_hooks
}

# Run a hook, looking for a regex in its stdout, and eval the matched lines.
# $1 is the hook to run
# $2 is the regex to look for
function eval_run_d () {
    local run_output=$(mktemp)
    rm $run_output
}

function cleanup_build_dir () {
  if ! timeout 5  sh -c " while ! sudo rm -rf $TMP_BUILD_DIR/built; do sleep 1; done"; then
    echo "ERROR: unable to cleanly remove $TMP_BUILD_DIR/built"
    exit 1
  fi
  if [ -f $TMP_MOUNT_PATH ]; then 
      //sudo rm -rf $TMP_MOUNT_PATH
   fi
  rm -rf --one-file-system $TMP_BUILD_DIR
  losetup -D
}

function run_d () {
    check_hooks 
    check_break before-$1 ${break_cmd:-bash}
    if [ -d ${TMP_HOOKS_PATH}/$1.d ]; then
        if [ -n "$2" ]; then
            $SCRIPT_HOME/dib-run-parts ${TMP_HOOKS_PATH}/$1.d | tee $2
            if [[ ${PIPESTATUS[0]} != 0 ]]; then
                return 1
            fi
        else 
            $SCRIPT_HOME/dib-run-parts ${TMP_HOOKS_PATH}/$1.d
        fi
    fi
    check_break after-$1 bash
}

function detach_loopback() {
    local loopdev=$1

    # Remove the map if it exists
    # If setup on a rhel or derivative the map was created with kpartx not losetup
    # and subsequently needs to be removed.
    loopdev_name=$(echo $loopdev | sed 's/\/dev\///g')

    if sudo dmsetup ls | grep $loopdev_name; then    
        mapper_name=$(sudo dmsetup ls | grep $loopdev_name | awk '{ print $1 }')
        sudo dmsetup --noudevsync remove $mapper_name
    fi

    # loopback dev may be tied up a bit by udev events triggered by partition events
    for try in $(seq 10 -1 1) ; do
        if ! sudo losetup $loopdev || sudo losetup -d $loopdev ; then
            return 0
        fi
        echo $loopdev may be busy, sleeping up to $try more seconds...
        sleep 1
    done
    echo Gave up trying to detach $loopdev
    return 1 
}

function create_base() {
    mkdir $TMP_BUILD_DIR/mnt
    export TMP_MOUNT_PATH=$TMP_BUILD_DIR/mnt
    # Copy data in to the root.
    TARGET_ROOT=$TMP_MOUNT_PATH run_d root 
    if [ -z "$(ls $TMP_MOUNT_PATH | grep -v '^lost+found\|tmp$')" ] ; then
        # No root element copied in. Note the test above allows
        # root.d elements to put things in /tmp
        echo "Failed to deploy the root element."
        exit 1
    fi

    # Configure Image
    # Setup resolv.conf so we can chroot to install some packages
    if [ -L $TMP_MOUNT_PATH/etc/resolv.conf ] || [ -f $TMP_MOUNT_PATH/etc/resolv.conf ] ; then
        sudo mv $TMP_MOUNT_PATH/etc/resolv.conf $TMP_MOUNT_PATH/etc/resolv.conf.ORIG
    fi

    # Recreate resolv.conf
    sudo touch $TMP_MOUNT_PATH/etc/resolv.conf
    sudo chmod 777 $TMP_MOUNT_PATH/etc/resolv.conf
    # use system configured resolv.conf if available to support internal proxy resolving 
    if [ -e /etc/resolv.conf ]; then
        cat /etc/resolv.conf > $TMP_MOUNT_PATH/etc/resolv.conf
    else 
        echo nameserver 8.8.8.8 > $TMP_MOUNT_PATH/etc/resolv.conf
    fi
    mount_proc_dev_sys
}

function mount_proc_dev_sys () {
  # supporting kernel file systems
  sudo mount -t proc none $TMP_MOUNT_PATH/proc
  sudo mount --bind /dev $TMP_MOUNT_PATH/dev
  sudo mount --bind /dev/pts $TMP_MOUNT_PATH/dev/pts
  sudo mount -t sysfs none $TMP_MOUNT_PATH/sys
}

# Recursively unmount directories under a given directory DIR
# usage:
#   unmount_dir DIR
function unmount_dir () {
    local dir="$1"
    local real_dir 
    local mnts
  
    if [ ! -d $dir ]; then
        echo "*** $dir is not a directory"
        return 1
    fi
  
    # get rid of any symlink elements in the incoming path, because
    # /proc/mounts is the real path
    real_dir=$(readlink -e $dir)
  
    mnts=$(awk '{print $2}' < /proc/mounts | grep "^$real_dir" | sort -r)
    for m in $mnts; do
        echo "Unmount $m"
        sudo umount -fl $m || true
    done
}

# set nu 
