#!bash
# vim:ff=unix:enc=utf8:ts=3:sw=3:et

# src2pkg-ng - package creation toolkit
# Copyright (C) 2005-2009 Gilbert Ashley
# Copyright (C) 2009 Timothy Goya

# src2pkg-ng is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2 as 
# published by the Free Software Foundation

# src2pkg-ng is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with src2pkg-ng.  If not, see <http://www.gnu.org/licenses/>.

{
   shopt -s nullglob
   declare HANDLER
   for HANDLER in "$SRC2PKG_NG_DIR/build"/* ; do
      source $HANDLER
   done
   shopt -u nullglob
}

configure_src() {
   declare CONFIGURE_TYPE="$1"
   declare SRC_DIR="$2"
   shift 2
   declare CONFIG_DIR="$SRC_DIR/$CONFIG_SUBDIR"
   configure_cmd_$CONFIGURE_TYPE "$CONFIG_DIR" "$@"
   declare CONFIGURE_CMD="$RET_CMD"
   if [[ "$CONFIGURE_CMD" ]] ; then
      set +e
      tprintf "@summary{Sandbox self-check}: "
      declare WARNING
      WARNING="$($SANDBOX -c "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" 2>&1)"
      declare CHECK=$?
      if (( CHECK == 0 )) ; then
         tprintf $"@success{Passed!}\n"
      else
         tprintf $"@error{Failed!}\n"
      fi
      if [[ "$WARNING" ]] ; then
         echo "$WARNING"
      fi
      if (( CHECK != 0 )) ; then
         cleanup $CHECK
      fi
      set -e
      tprintf $"@summary{Configuring sources using}\n"
      echo  " $CONFIGURE_CMD"
      IFS=$' \n\t'
      set +eu
      CFLAGS="$ARCH_FLAGS" \
      CXXFLAGS="$ARCH_FLAGS" \
      $SANDBOX "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" \
         -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" \
         /bin/sh -c "cd $CONFIG_DIR && $CONFIGURE_CMD" > "$SRC_DIR/$NAME-configure.log" 2>&1
      declare STATUS=$?
      set -eu
      IFS=$'\n'
      if (( STATUS == 0 )) ; then
         tprintf "@summary{Configuration} - @success{Successful!}!\n"
      else
         tprintf $"@error{Error!}: Configuring sources failed\n"
         cleanup $STATUS
      fi
   else
      tprintf $"@warning{Warning!}: No configure command returned by handler\n"
   fi
}

compile_src() {
   declare COMPILE_TYPE="$1"
   declare SRC_DIR="$2"
   shift 2
   declare CONFIG_DIR="$SRC_DIR/$CONFIG_SUBDIR"
   compile_cmd_$COMPILE_TYPE "$CONFIG_DIR" "$@"
   declare COMPILE_CMD="$RET_CMD"
   if [[ "$COMPILE_CMD" ]] ; then
      set +e
      tprintf "@summary{Sandbox self-check}: "
      declare WARNING
      WARNING="$($SANDBOX -c "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" 2>&1)"
      declare CHECK=$?
      if (( CHECK == 0 )) ; then
         tprintf $"@success{Passed!}\n"
      else
         tprintf $"@error{Failed!}\n"
      fi
      if [[ "$WARNING" ]] ; then
         echo "$WARNING"
      fi
      if (( CHECK != 0 )) ; then
         cleanup $CHECK
      fi
      set -e
      tprintf $"@summary{Compiling sources using}\n"
      echo  " $COMPILE_CMD"
      IFS=$' \n\t'
      set +eu
      CFLAGS="$ARCH_FLAGS" \
      CXXFLAGS="$ARCH_FLAGS" \
      $SANDBOX "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" \
         -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" \
         /bin/sh -c "cd $CONFIG_DIR && $COMPILE_CMD" > "$SRC_DIR/$NAME-compile.log" 2>&1
      declare STATUS=$?
      set -eu
      IFS=$'\n'
      if (( STATUS == 0 )) ; then
         tprintf "@summary{Compilation} - @success{Successful!}!\n"
      else
         tprintf $"@error{Error!}: Compiling sources failed\n"
         cleanup $STATUS
      fi
   else
      tprintf $"@warning{Warning!}: No compile command returned by handler\n"
   fi
}

safe_install() {
   declare INSTALL_TYPE="$1"
   declare SRC_DIR="$2"
   declare PKG_DIR="$3"
   shift 3
   declare CONFIG_DIR="$SRC_DIR/$CONFIG_SUBDIR"
   if [[ "${1:-""}" ]] ; then
      install_cmd_$INSTALL_TYPE "$CONFIG_DIR" "$PKG_DIR" "$@"
   else
      install_cmd_$INSTALL_TYPE "$CONFIG_DIR" "$PKG_DIR" "install"
   fi
   declare INSTALL_CMD="$RET_CMD"
   if [[ "$INSTALL_CMD" ]] ; then
      set +e
      tprintf "@summary{Sandbox self-check}: "
      declare WARNING
      WARNING="$($SANDBOX -c -w "$PKG_DIR" "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" 2>&1)"
      declare CHECK=$?
      if (( CHECK == 0 )) ; then
         tprintf $"@success{Passed!}\n"
      else
         tprintf $"@error{Failed!}\n"
      fi
      if [[ "$WARNING" ]] ; then
         echo "$WARNING"
      fi
      if (( CHECK != 0 )) ; then
         cleanup $CHECK
      fi
      set -e
      mkdir -p "$PKG_DIR"
      tprintf $"@summary{Installing sources using}\n"
      echo  " $INSTALL_CMD"
      IFS=$' \n\t'
      set +eu
      $SANDBOX -w "$PKG_DIR" "${DEPS_DIRS[@]/#/-r}" -r "$SYSTEM_DIR" \
         -e /dev -e /proc -e /sys -e /tmp -e /var/tmp -e "$SRC_DIR" \
         /bin/sh -c "cd $CONFIG_DIR && $INSTALL_CMD" > "$SRC_DIR/$NAME-install.log" 2>&1
      declare STATUS=$?
      set -eu
      IFS=$'\n'
      if (( STATUS == 0 )) ; then
         tprintf "@summary{Installation} - @success{Successful!}!\n"
      else
         tprintf $"@error{Error!}: Installing sources failed\n"
         cleanup $STATUS
      fi
   else
      tprintf $"@warning{Warning!}: No install command returned by handler\n"
   fi
   if [[ ! "$(find "$PKG_DIR" -type f)" ]] ; then
      tprintf $"@error{Error!}: The package tree has no content!\n"
      cleanup 1
   fi
}

install_extra() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   if (( INSTALL_DOCS )) ; then
      install_docs "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_PKGCONFIG )) ; then
      install_pkgconfig "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_XINIT )) ; then
      install_xinit "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_INIT )) ; then
      install_init "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_CONF )) ; then
      install_conf "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_ICONS )) ; then
      install_icons "$SRC_DIR" "$PKG_DIR"
   fi
   if (( INSTALL_DESKTOP )) ; then
      install_desktop "$SRC_DIR" "$PKG_DIR"
   fi
}

install_docs() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   declare PATTERNS=()
   push_back PATTERNS "ABOUT"
   push_back PATTERNS "ANNOUNCE"
   push_back PATTERNS "AUTHORS"
   push_back PATTERNS "BUGS"
   push_back PATTERNS "CHANGELOG"
   push_back PATTERNS "CHANGES"
   push_back PATTERNS "ChangeLog"
   push_back PATTERNS "Changelog"
   push_back PATTERNS "CONFIGURATION"
   push_back PATTERNS "CONTRIBUTORS"
   push_back PATTERNS "COPYING*"
   push_back PATTERNS "COPYRIGHT"
   push_back PATTERNS "CREDITS"
   push_back PATTERNS "FAQ"
   push_back PATTERNS "FEATURES"
   push_back PATTERNS "GPL*"
   push_back PATTERNS "gpl*"
   push_back PATTERNS "History"
   push_back PATTERNS "HINTS"
   push_back PATTERNS "HISTORY"
   push_back PATTERNS "INSTALL"
   push_back PATTERNS "LGPL*"
   push_back PATTERNS "lgpl*"
   push_back PATTERNS "LICENSE*"
   push_back PATTERNS "LICENCE*"
   push_back PATTERNS "License*"
   push_back PATTERNS "Licence*"
   push_back PATTERNS "license*"
   push_back PATTERNS "licence*"
   push_back PATTERNS "LSM"
   push_back PATTERNS "$NAME-$VERSION.lsm"
   push_back PATTERNS "$NAME.lsm"
   push_back PATTERNS "MANIFEST"
   push_back PATTERNS "NEWS"
   push_back PATTERNS "PKGINFO"
   push_back PATTERNS "PKG-INFO"
   push_back PATTERNS "README*"
   push_back PATTERNS "*.README"
   push_back PATTERNS "ReadMe*"
   push_back PATTERNS "Readme*"
   push_back PATTERNS "readme*"
   push_back PATTERNS "readme*"
   push_back PATTERNS "THANKS"
   push_back PATTERNS "TIPS"
   push_back PATTERNS "TODO"
   push_back PATTERNS "VERSION"
   declare -a DOCS
   declare PATTERN
   for PATTERN in "${PATTERNS[@]}" ; do
      push_back DOCS $(find "$SRC_DIR" -name "$PATTERN" -maxdepth 1 -type f)
   done
   mkdir -p "$PKG_DIR/$DOC_DIR"
   if (( ${#DOCS[@]} )) ; then
      tprintf "@summary{Installing docs} - "
      declare DOC
      for DOC in "${DOCS[@]}" ; do
         cp -af "$DOC" "$PKG_DIR/$DOC_DIR"
      done
      tprintf $"@success{Done}\n"
   fi
}

install_pkgconfig() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   if ! [[ "$(find "$PKG_DIR" -name "*.pc" -type f)" ]] ; then
      shopt -s nullglob
      declare PKGCONFIGS=($(find "$SRC_DIR" -name "*.pc" ! -name "*uninstalled.pc" -type f) "$SOURCES_DIR"/*.pc)
      shopt -u nullglob
      if (( ${#PKGCONFIGS[@]} )) ; then
         tprintf "@summary{Installing pkgconfig} - "
         declare PKGCONFIG
         for PKGCONFIG in "${PKGCONFIGS[@]}" ; do
            if grep -q Cflags "$PKGCONFIG" ; then
               mkdir -p "$PKG_DIR/$LIB_DIR/pkgconfig"
               cp -f "$PKGCONFIG" "$PKG_DIR/$LIB_DIR/pkgconfig"
            fi
         done
         tprintf $"@success{Done}\n"
      fi
   fi
}

install_xinit() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   if ! [[ "$(find "$PKG_DIR" -name "xinitrc.*" -type f)" ]] ; then
      shopt -s nullglob
      declare XINITS=($(find "$SRC_DIR" -name "xinitrc.*") "$SOURCES_DIR"/xinitrc.*)
      shopt -u nullglob
      if (( ${#XINITS[@]} )) ; then
         tprintf "@summary{Installing xinit} - "
         declare XINIT
         for XINIT in "${XINITS[@]}" ; do
            mkdir -p "$PKG_DIR/$SYSCONF_DIR/X11/xinit"
            cp -af "$XINIT" "$PKG_DIR/$SYSCONF_DIR/X11/xinit"
         done
         tprintf $"@success{Done}\n"
      fi
   fi
}

install_init() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   if ! [[ "$(find "$PKG_DIR" -name "rc.*" -type f)" ]] ; then
      shopt -s nullglob
      declare INITS=($(find "$SRC_DIR" -name "rc.*") "$SOURCES_DIR"/rc.*)
      shopt -u nullglob
      if (( ${#INITS[@]} )) ; then
         tprintf "@summary{Installing init} - "
         declare INIT
         for INIT in "${INITS[@]}" ; do
            # FIXME: what's the correct distro-specific thing to do?
            mkdir -p "$PKG_DIR/$SYSCONF_DIR/rc.d"
            cp -af "$INIT" "$PKG_DIR/$SYSCONF_DIR/rc.d"
         done
         tprintf $"@success{Done}\n"
      fi
   fi
}

install_conf() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   if [[ -f "$PKG_DIR/$SYSCONF_DIR/$NAME.conf" || -f "$PKG_DIR/$SYSCONF_DIR/${NAME}rc" ]] ; then
      declare -a CONFS
      if [[ -f "$SOURCES_DIR/$NAME.conf" ]] ; then
         push_back CONFS "$SOURCES_DIR/$NAME.conf"
      fi
      if [[ -f "$SOURCES_DIR/${NAME}rc" ]] ; then
         push_back CONFS "$SOURCES_DIR/${NAME}rc"
      fi
      if (( ${#CONFS[@]} )) ; then
         tprintf "@summary{Installing conf} - "
         declare CONF
         for CONF in "${CONFS[@]}" ; do
            mkdir -p "$PKG_DIR/$SYSCONF_DIR"
            cp -af "$CONF" "$PKG_DIR/$SYSCONF_DIR"
         done
         tprintf $"@success{Done}\n"
      fi
   fi
}

install_icons() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   # FIXME: Split each image type into it's own function
   # FIXME: Don't do anything if the installer already did something
   declare XPMS=($(find "$SRC_DIR" -name "$NAME.xpm"))
   if [[ -f "$SOURCES_DIR/$NAME.xpm" ]] ; then
      push_back XPMS "$SOURCES_DIR/$NAME.xpm"
   fi
   declare PNGS=($(find "$SRC_DIR" -name "$NAME.png"))
   if [[ -f "$SOURCES_DIR/$NAME.png" ]] ; then
      push_back PNGS "$SOURCES_DIR/$NAME.png"
   fi
   declare SVGS=($(find "$SRC_DIR" -name "$NAME.svg"))
   if [[ -f "$SOURCES_DIR/$NAME.svg" ]] ; then
      push_back SVGS "$SOURCES_DIR/$NAME.svg"
   fi
   if (( ${#XPMS[@]} )) || (( ${#PNGS[@]} )) || (( ${#SVGS[@]} )) ; then
      tprintf "@summary{Installing icons} - "
      set +u
      declare XPM
      for XPM in "${XPMS[@]}" ; do
         mkdir -p "$PKG_DIR/$PIXMAPS_DIR"
         cp -af "$XPM" "$PKG_DIR/$PIXMAPS_DIR"
      done
      declare PNG
      for PNG in "${PNGS[@]}" ; do
         mkdir -p "$PKG_DIR/$ICONS_DIR/hicolor/48x48/apps"
         cp -af "$PNG" "$PKG_DIR/$ICONS_DIR/hicolor/48x48/apps"
      done
      declare SVG
      for SVG in "${SVGS[@]}" ; do
         mkdir -p "$PKG_DIR/$ICONS_DIR/hicolor/scalable/apps"
         cp -af "$SVG" "$PKG_DIR/$ICONS_DIR/hicolor/scalable/apps"
      done
      set -u
      tprintf $"@success{Done}\n"
   fi
}

install_desktop() {
   declare SRC_DIR="$1"
   declare PKG_DIR="$2"
   shopt -s nullglob
   declare DESKTOPS=($(find "$SRC_DIR" -name "*.desktop") "$SOURCES_DIR"/*.desktop)
   shopt -u nullglob
   if ! [[ "$(find "$PKG_DIR" -name "*.desktop" -type f)" ]] ; then
      if (( ${#DESKTOPS[@]} )) ; then
         tprintf "@summary{Installing desktop} - "
         declare DESKTOP
         for DESKTOP in "${DESKTOPS[@]}" ; do
            if [[ -f "$PKG_DIR/$SYSCONF_DIR/X11/xinit/xinitrc.$NAME" && $(basename "$DESKTOP" | tr "[:upper:]" "[:lower:]") == $(echo "$NAME.desktop" | tr "[:upper:]" "[:lower:]") ]] ; then
               mkdir -p "$PKG_DIR/$DATA_DIR/xsesssions"
               cp "$DESKTOP" "$PKG_DIR/$DATA_DIR/xsesssions"
            else
               mkdir -p "$PKG_DIR/$DATA_DIR/applications"
               cp "$DESKTOP" "$PKG_DIR/$DATA_DIR/applications" 
            fi
         done
         tprintf $"@success{Done}\n"
      fi
   fi
}
