#!/bin/sh

# Author   : Benoit PAPILLAULT <benoit.papillault@sourcemage.org>
# Creation : 2004-11-25

# Design document:
# http://benoit.papillault.free.fr/sourcemage/cast-binary.php

# usage: get_cache_list
# output the list of files available, the output name should not include
# any URL or path.

get_cache_list()
{
  if [ -d "${BASE}" ]; then
	# cut removes the leading "./"
    find "${BASE}" -type f -maxdepth 1 | cut -c3-
  else
    if ! wget -O - "${BASE}/ls"; then
	  return 1
    fi
  fi
}

# usage: get_cache spell
# return the full path to spell-....tar.bz2

get_cache()
{
  local spell="$1"
  local CACHE=`get_cache_list | grep "^${spell}_" | head -n 1` &&
  if [ -n "${CACHE}" ]; then
    if [ -f "${BASE}/${CACHE}" ]; then
	  echo "${BASE}/${CACHE}"
    else
	  # it's a remote file, we need to download it first in /tmp
	  rm -rf "/tmp/${CACHE}" &&
	  if wget -O "/tmp/${CACHE}" "${BASE}/${CACHE}"; then
		echo "/tmp/${CACHE}"
	  fi
	fi
  fi
}

# usage: update_sorcery_packages spell version

update_sorcery_packages()
{
  local SPELL="$1"
  local VERSION="$2"

  mkdir -p "${INSTALL_ROOT}/var/state/sorcery" &&
  echo "${SPELL}:`date +%Y%m%d`:installed:${VERSION}" \
    >> "${INSTALL_ROOT}/var/state/sorcery/packages"
}

# usage: update_sorcery_depends
# add stdin to sorcery depends on the destination system

update_sorcery_depends()
{
  local depends="$1"

  mkdir -p "${INSTALL_ROOT}/var/state/sorcery" &&
  cat >> "${INSTALL_ROOT}/var/state/sorcery/depends"
}

# usage: install_from_cache spell cache.tar.bz2

install_from_cache()
{
  local SPELL="$1"
  local CACHE="$2"
  local VERSION=`basename "${CACHE}" | cut -d_ -f2`

  echo "spell ${SPELL} version ${VERSION} is being investigated"

# create a temporary directory
  local tmpdir="/tmp/spell-binary-$$"
  rm -rf "${tmpdir}" && mkdir -p "${tmpdir}" &&
  (

# extract and install dependencies
	tar jxf "${CACHE}" -C "${tmpdir}" ./install &&
	grep ".*:.*:on:.*" "${tmpdir}/install/depends" |
	cut -d: -f2 | cut -d'(' -f1 |
	while read dep_spell;
	do
	  spell-binary-install "${dep_spell}"
	done

# extract binary files

    echo "spell ${SPELL} version ${VERSION} is being installed"

	cat "${CACHE}" |
	(
	  cd "${INSTALL_ROOT}" &&
	  tar jxf - --exclude ./install 2>/dev/null
	)

# update sorcery files:
# - /var/state/sorcery/packages
# - /var/state/sorcery/depends

	update_sorcery_packages "${SPELL}" "${VERSION}"
	cat "${tmpdir}/install/depends" | update_sorcery_depends

# run post installation script
	(
	  cd "${INSTALL_ROOT}" &&
	  if [ -x "${tmpdir}/install/postinst" ]; then
		"${tmpdir}/install/postinst"
	  fi
	)

  ) &&
  echo "spell ${SPELL} version ${VERSION} is installed"

  rm -rf "${tmpdir}"
}

# usage: install_from_system spell

install_from_system()
{
  local SPELL="$1"

# we check if the spell is in the source system
  local packages="/var/state/sorcery/packages"
  if [ ! -f "${packages}" ]; then
    echo "spell ${SPELL} is missing"
	exit 1
  fi

  if ! grep -q "^${SPELL}:" "${packages}"; then
    echo "spell ${SPELL} is missing"
    exit 1
  fi

  local VERSION=`grep "^${SPELL}:" "${packages}" | cut -d: -f4 | head -n 1`

  echo "spell ${SPELL} version ${VERSION} is being investigated"

# find the install log
  local FILES="/var/log/sorcery/install/${SPELL}-${VERSION}"
  if [ ! -f "${FILES}" ]; then
    echo "spell ${SPELL} is missing an install log"
    exit 1
  fi

# install dependencies

  local depends="/var/state/sorcery/depends"
  if [ -f "${depends}" ]; then
    grep "^${SPELL}:.*:on:.*" | cut -d: -f2 | cut -d'(' -f1|
	while read dep_spell;
	do
	  spell-binary-install "${dep_spell}"
	done
  fi

# create a temporary dir
  local tmpdir="/tmp/spell-binary-$$"
  rm -rf "${tmpdir}" && mkdir -p "${tmpdir}"

# extract binary files

  echo "spell ${SPELL} version ${VERSION} is being installed"

  sed 's:^\(/*\)::' "${FILES}" > "${tmpdir}/ls"

  (cd / && tar cfl - --no-recursion -T "${tmpdir}/ls" 2>/dev/null)|
  (cd "${INSTALL_ROOT}" && tar xfp - 2>/dev/null) || exit 1

# update sorcery files

  update_sorcery_packages "${SPELL}" "${VERSION}"
  grep "^${SPELL}:" "${depends}" | update_sorcery_depends 

# run post installation scripts: how?

  rm -rf "${tmpdir}"

  echo "spell ${SPELL} version ${VERSION} is installed"
}

main()
{
  if [ $# -ne 1 ]; then
    echo "usage: $0 spell"
    exit 1
  fi

  local SPELL="$1"

# default values
  if [ -z "${BASE}" ]; then
    BASE=.
  fi

  if [ -z "${INSTALL_ROOT}" ]; then
    INSTALL_ROOT=/
  fi

# check if the spell is already installed first!
  if [ -f "${INSTALL_ROOT}/var/state/sorcery/packages" ]; then
    if grep -q "^${SPELL}:" "${INSTALL_ROOT}/var/state/sorcery/packages"; then
      echo "spell ${SPELL} is already installed"
      exit 0
    fi
  fi

# find the cache file
  local CACHE=`get_cache "${SPELL}"`
  if [ -z "${CACHE}" ]; then
	install_from_system "${SPELL}"
  else
    install_from_cache "${SPELL}" "${CACHE}"
  fi
}

main "$@"
