#! /bin/sh
#
# Determine package dependencies from installed-pkg-config file
#
# Copyright (C) 2006-2007 Arjan Oosting <arjan@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of either:
#
# 1) The terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program 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 this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# 2) BSD 3-clause license.
# 
#    All rights reserved.
#
#    Redistribution and use in source and binary forms, with or without
#    modification, are permitted provided that the following conditions are
#    met:
#
#      * Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#
#      * Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided
#        with the distribution.
#
#      * The names of contributors may not be used to endorse or promote
#        products derived from this software without specific prior
#        written permission. 
#
#    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

set -e 

sort_uniq(){
    { 
	for i in "$@" ; do
	    echo $i
	done
    } | sort -u | tr "\n" " "
}

dependency(){
    local package
    local version
    local next_upstream_version
    package=$1
    version=`dpkg-query --showformat='${Version}' -W $package` 
    next_upstream_version=`echo $version | sed  -e 's/-[^-]*$//' -e 's/$/+/'`
    echo "$package (>= $version), $package (<< $next_upstream_version)"
}

dependencies(){
    local package
    local packages
    local deps
    packages=$@
    for package in `sort_uniq $packages` ; do
	deps="$deps, `dependency $package`"
    done

    echo $deps | sed -e 's/^,[ ]*//'
}

providing_package_for_ghc6(){
    local package
    local dep
    local dir
    local dirs
    local lib
    dep=$1
    dirs=`ghc-pkg6 field $dep library-dirs | cut -d':' -f 2`
    lib=`ghc-pkg6 field $dep hs-libraries | sed -e 's|hs-libraries: *\([^ ]*\).*|\1|' `
    for dir in $dirs ; do
	if [ -e "${dir}/lib${lib}.a" ] ; then
	    package=`dpkg-query -S ${dir}/lib${lib}.a | cut -d':' -f 1` || exit $?
	    continue
	fi
    done
    echo $package
}

providing_package_for_ghc6_prof(){
    local package
    local dep
    local dir
    local dirs
    local lib
    dep=$1
    dirs=`ghc-pkg6 field $dep library-dirs | cut -d':' -f 2`
    lib=`ghc-pkg6 field $dep hs-libraries | sed -e 's|hs-libraries: *\([^ ]*\).*|\1|' `
    for dir in $dirs ; do
	if [ -e "${dir}/lib${lib}_p.a" ] ; then
	    package=`dpkg-query -S ${dir}/lib${lib}_p.a | cut -d':' -f 1` || exit $?
	    continue
	fi
    done
    echo $package
}

cabal_depends(){
    local config
    local dep
    local depends
    local final_depends
    until [ -z "$1" ]
    do
      config=$1
      depends="$depends `grep-dctrl -n -i -s Depends "" $config | tr "," " "`"
      shift
    done
    for dep in `sort_uniq $depends` ; do
	# The package is not mentioned in the ignored package list with the same version 
	# or mentioned without any version in the ignored package list?
	if  echo " $ignores " | grep -qv " $dep " && 
	    echo " $ignores " | grep -qv " `echo $dep | sed s%-[0-9][.0-9a-zA-Z]*$%%` " ; 
	then
	    final_depends="$final_depends $dep"
	fi
    done
    echo $final_depends
}

depends_for_ghc6(){
    local dep
    local packages
    for dep in `cabal_depends $@` ; do
	packages="$packages `providing_package_for_ghc6 $dep`"
    done
 
    dependencies $packages
}

depends_for_ghc6_prof(){
    local dep
    local packages
    for dep in `cabal_depends $@` ; do
	packages="$packages `providing_package_for_ghc6_prof $dep`"
    done
 
    dependencies $packages
}

depends_for_hugs(){
    local version
    local upstream_version
    version=`dpkg-query --showformat='${Version}' -W hugs`
    upstream_version=`echo $version | sed -e 's/-[^-]*$//'`
    echo "hugs (>= $upstream_version)"
}

find_config_for_ghc6(){
    local f
    local pkg
    pkg=$1
    case "$pkg" in
	libghc6-*-prof)
	    pkg=`echo $pkg | sed -e 's/-prof$/-dev/'`
	    ;;
	*)
	    ;;
    esac
    for f in debian/$pkg/usr/lib/haskell-packages/ghc6/lib/*/installed-pkg-config ; do
	if [ -f "$f" ] ; then
	    echo $f
	    break
	fi
    done
}


if ! [ `which grep-dctrl` > /dev/null ] ; then 
    echo "grep-dctrl is missing" >&2 
    exit 1
fi

args=
ignores=
files=
until [ -z "$1" ]
do 
  case "$1" in
      -X*)
          pkg=${1##-X}
	  ignores="$ignores $pkg"
	  ;;

      --exclude=*)
	  pkg=${1##--exclude=}
	  ignores="$ignores $pkg"
	  ;;

      -*)
	  args="$args $1"
	  ;;
      *)
	  if [ -f $1 ] ; then
	      files="$files $1"
	  else
	      echo "Installed package description file $1 can not be found" >&2
	      exit 1
	  fi
	  ;;
  esac
  shift
done

for pkg in `dh_listpackages $args`; do
    sfile=debian/$pkg.substvars
    touch $sfile

    case "$pkg" in
	libghc6-*-dev|libghc6-*-prof)
	    config=`find_config_for_ghc6 $pkg`
	    if [ -f "$config" ] ; then
		cfiles="$files $config"
	    else
		cfiles="$files"
	    fi
	    if [ -z "$cfiles" ] ; then
	      echo "No installed package description files can not be found" >&2
	      exit 1
	    fi
	    grep -v ^haskell:Depends $sfile > $sfile.tmp || true
	    case "$pkg" in
		libghc6-*-dev)
		    echo "haskell:Depends=`depends_for_ghc6 $cfiles`" >> $sfile.tmp
		    ;;
		libghc6-*-prof)
		    echo "haskell:Depends=`depends_for_ghc6_prof $cfiles`" >> $sfile.tmp
		    ;;
	    esac
	    mv $sfile.tmp $sfile
	    ;;
	libhugs-*)
	    grep -v ^haskell:Depends $sfile > $sfile.tmp || true
	    echo "haskell:Depends=`depends_for_hugs`" >> $sfile.tmp
	    mv $sfile.tmp $sfile
	    ;;
	*)
	    ;;
    esac
done
