#!/bin/bash
# Authors: Sabayon Team

set -e

export REPOSITORY_NAME="${REPOSITORY_NAME:-$(basename $(pwd))}"
export LC_ALL=en_US.UTF-8

export SAB_WORKSPACE="${SAB_WORKSPACE:-$PWD}"
export SAB_ARTIFACTS_DIR="${SAB_ARTIFACTS_DIR:-artifacts}"
export SAB_ARCH="${SAB_ARCH:-intel}"

# Add skip env print if there are env vars with credentials.
export SKIP_PRINTENV="${SKIP_PRINTENV:-0}"
export SAB_BUILDFILE="${SAB_BUILDFILE:-build.yaml}"

export SAB_STAGING_DIRS="${SAB_STAGING_DIRS:-staging1 staging2}"

# Pkgs-checker filter option
export PKGS_CHECKER_FILTER_OPTS="${PKGS_CHECKER_FILTER_OPTS:--v -L INFO -r ${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/ -f ${SAB_BUILDFILE}}"
export PKGS_CHECKER_PKGLIST_OPTS="${PKGS_CHECKER_PKGLIST_OPTS:--v -L INFO}"

. /sbin/sark-functions.sh

if [ ! -e "${SAB_BUILDFILE}" ]; then
    echo "Must be run from a repository directory containing a ${SAB_BUILDFILE}"
    exit 1
fi

if [ -z "${SAB_STAGING_DIRS}" ] ; then
    echo "No staging dirs defined"
    exit 1
fi

load_env_from_yaml ${SAB_BUILDFILE}

export OUTPUT_DIR="${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${REPOSITORY_NAME}-binhost"
export CHECK_BUILD_DIFFS=${CHECK_BUILD_DIFFS:-1}

NEW_BINHOST_MD5=$(mktemp -t "$(basename $0).XXXXXXXXXX")
OLD_BINHOST_MD5=$(mktemp -t "$(basename $0).XXXXXXXXXX")

[ -d ${OUTPUT_DIR} ] || mkdir -p "${OUTPUT_DIR}"
[ "$CHECK_BUILD_DIFFS" -eq 1 ] && packages_hash ${SAB_WORKSPACE} $REPOSITORY_NAME $OLD_BINHOST_MD5

# Debug what env vars are being passed to the builder
if [ "${SKIP_PRINTENV}" != 1 ] ; then
  printenv | sort
fi

[ -d /usr/portage/packages ] || mkdir -p /usr/portage/packages

FILTER_DIR="${FILTER_DIR:-$(mktemp -d)}"

# Copy binhosts from staging directories
for dir in ${SAB_STAGING_DIRS} ; do

    [ ! -d ${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${dir} ] && {
        echo "Skipping staging directory ${dir}."
        continue
    }

    pushd ${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${dir}

    # Copy files from any binhost directory
    binhost_dirs=$(ls --color=none -d ./*-binhost)

    for bhd in ${binhost_dirs} ; do
        if [ -d ${bhd} ] ; then
          cp -rvf ${bhd}/* ${FILTER_DIR} || true
        fi
    done

    popd
done

# Filter inject of the files
echo "=== Filter packages ==="
${PKGS_CHECKER_BIN} filter ${PKGS_CHECKER_FILTER_OPTS} -d ${FILTER_DIR} || {
  echo "Error on filter packages"
  exit 1
}
echo "=== Filter packages completed ==="

if [ "$CHECK_BUILD_DIFFS" -eq 1 ]; then
  cp -rvf ${FILTER_DIR}/* ${OUTPUT_DIR} || true
else
  cp -rvf ${FILTER_DIR}/* /usr/portage/packages || true
fi

# If is execute eit pull then we need install all repo packages to avoid
# that not installed packages are handled as to remove.
if [ "$SKIP_PULL" = "0" ] ; then
  if [ -n "$SAB_STAGING_BUILD_RESOURCES" ] ; then
    for r in $SAB_STAGING_BUILD_RESOURCES ; do
      pkgs_checker_sark_list_opts="$pkgs_checker_sark_list_opts -s $r"
    done

    repo_pkgs=$(${PKGS_CHECKER_BIN} sark pkglist $pkgs_checker_sark_list_opts)

    if [ -n "${repo_pkgs}" ] ; then
      equo i --relaxed $repo_pkgs || {
        echo "Error on install repository packages"
        exit 1
      }
    else
      echo "No packages of repo ${REPOSITORY_NAME} available."
    fi
  fi
fi

TEMPDIR=$(mktemp -d)

# Checking diffs
if [ "$CHECK_BUILD_DIFFS" -eq 1 ]; then
  echo "*** Checking tbz2 diffs ***"
  # let's do the hash of the tbz2 without xpak data
  packages_hash ${SAB_WORKSPACE}  $REPOSITORY_NAME $NEW_BINHOST_MD5
  TO_INJECT=($(diff -ru $OLD_BINHOST_MD5 $NEW_BINHOST_MD5 | grep -v -e '^\+[\+]' | grep -e '^\+' | awk '{print $2}'))

  echo "INJECT RESULT = ${TO_INJECT[@]}"

  #if diffs are detected, regenerate the repository
  if diff -q $OLD_BINHOST_MD5 $NEW_BINHOST_MD5 >/dev/null ; then
    echo "No changes where detected, repository generation prevented"

    rm -rf $OLD_BINHOST_MD5 $NEW_BINHOST_MD5
    exit 0
  else
    TBZ2_DIR=${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${REPOSITORY_NAME}-binhost
    echo "${TO_INJECT[@]} packages needs to be injected"
    for ((i=0; i<${#TO_INJECT[@]}; i++)) ; do
      # We need maintains category directory because
      # if there are two package with different category but with same
      # name and version, last win.
      dir=$(dirname ${TO_INJECT[$i]})
      echo "Copying ${TO_INJECT[$i]} to ${TEMPDIR}/${dir}..."
      mkdir -p ${TEMPDIR}/${dir} || true
      cp -rf "${TBZ2_DIR}"/${TO_INJECT[$i]} ${TEMPDIR}/${dir}/
    done
  fi
else
  # Inject all packages available under /usr/portage/packages
  cp -R /usr/portage/packages/* ${TEMPDIR} || true
fi

export PKGS_CACHE_DIR=$TEMPDIR
sark-localcreaterepo

# Clean staging directories from namespace/artficats.
for dir in ${SAB_STAGING_DIRS} ; do
    if [ -d ${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${dir} ] ; then
        echo "Cleanup staging directory ${dir}..."
        rm -rf ${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${dir}
    fi
done

# Create pkglist file of binhost directory
echo "Creating pkglist of binhost directory..."
${PKGS_CHECKER_BIN} pkglist create ${PKGS_CHECKER_PKGLIST_OPTS} \
  -d ${OUTPUT_DIR}/ -f ${OUTPUT_DIR}/${REPOSITORY_NAME}.pkglist

# Create report of binhost directory under artefacts
export PKGS_CHECKER_FILTER_ARTEFACTS_OPTS="${PKGS_CHECKER_FILTER_ARTEFACTS_OPTS:--v -L INFO --dry-run}"
${PKGS_CHECKER_BIN} filter ${PKGS_CHECKER_FILTER_ARTEFACTS_OPTS} -f ${SAB_BUILDFILE} -r ${OUTPUT_DIR}/${REPOSITORY_NAME} -d ${OUTPUT_DIR} || {
  echo "Error on filter artefacts binhost directory"
  exit 1
}

# Create pkglist json report
echo "Creating pkglist JSON report..."
repodir="${SAB_WORKSPACE}/${SAB_ARTIFACTS_DIR}/${REPOSITORY_NAME}"
${PKGS_CHECKER_BIN} pkglist show ${PKGS_CHECKER_PKGLIST_OPTS} \
  -r ${repodir}/PKGLIST-* -j -p --repo \
  ${REPOSITORY_NAME} --arch ${SAB_ARCH} > ${repodir}/pkglist.json || {
  echo "Error on create pkglist.json"
  exit 1
}

echo "=== sark-localinjector has completed the job. Bye. ==="
