#!@l_prefix@/lib/openpkg/bash
##
##  odoc -- OpenPKG doc packaging support
##  Copyright (c) 2000-2018 Ralf S. Engelschall <http://engelschall.com/>
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  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.
##

Line()
  # Emulate the 'line' command.
  # Copy one complete line unchanged from stdin to stdout.
{
  local line

  IFS= read -r line && echo "$line"
} # Line


ParseSpec()
  # in  : $1 - spec file name
  # out : $spName, $spSummary, $spURL, $spVendor, $spVersion, $spRelease,
  #       $spDescription
{
  local spec=$1
  local defs= defsep= nl=
  local var val doBreak

  while read -r l; do
      case "$l" in
	   "#"*) ;;
	   "%define"*)
	       set -- $l
	       var=$2
	       val=$3
	       defs="$defs${defsep}s,%{$var},$val,g"
	       defsep=";"
	       ;;
	   "Name:"*)
	       var=spName
	       val=`expr "$l" : 'Name:[ 	]*\(.*\)[ 	]*$'`
	       defs="$defs${defsep}s,%{name},$val,g"
	       defsep=";"
	       ;;
	   "Summary:"*)
	       var=spSummary
	       val=`expr "$l" : 'Summary:[ 	]*\(.*\)[ 	]*$'`
	       ;;
	   "URL:"*)
	       var=spURL
	       val=`expr "$l" : 'URL:[ 	]*\(.*\)[ 	]*$'`
	       ;;
	   "Vendor:"*)
	       var=spVendor
	       val=`expr "$l" : 'Vendor:[ 	]*\(.*\)[ 	]*$'`
	       ;;
	   "Version:"*)
	       var=spVersion
	       val=`expr "$l" : 'Version:[ 	]*\(.*\)[ 	]*$'`
	       defs="$defs${defsep}s,%{version},$val,g"
	       defsep=";"
	       ;;
	   "Release:"*)
	       var=spRelease
	       val=`expr "$l" : 'Release:[ 	]*\(.*\)[ 	]*$'`
	       defs="$defs${defsep}s,%{release},$val,g"
	       defsep=";"
	       ;;
	   "%description"*)
	       var=spDescription
	       val=
	       nl=
	       while read -r d; do
		   case "$d" in
		        "%track"*|"%prep"*|"%build"*) break;;
		   esac
	           val="$val$nl$d"
		   nl="<br>"
	       done
	       # Arglll (eval chokes on "'", as in "it's")
	       val=`echo $val | sed "s,','\"'\"',g"`
	       doBreak=1
	       ;;
            *) var=; doBreak=;;
      esac
      if   [ -n "$defs" ]
      then oldval=
           while [ "$val" != "$oldval" ]; do
               oldval=$val
               val=`echo "$val"|sed "$defs"` # %{macro} expansion
           done
      fi
      [ -n "$var"     ] && echo "$var='$val'"
      [ -n "$doBreak" ] && break;
  done <$spec
  true
} # ParseSpec


PrependRBR()
  # in : $1 - path
  # Prepends $RPM_BUILD_ROOT when path starts with $l_prefix.
{
  local path=$1

  case "$path" in
       $l_prefix|$l_prefix/*) echo "$RPM_BUILD_ROOT$path";;
  esac
} # PrependRBR


RemoveRBR()
  # in : $1 - path
  # Removes $RPM_BUILD_ROOT from beginning of path.
{
  local path=$1

  [ -z "$RPM_BUILD_ROOT" ] && return 0
  case "$path" in
       $RPM_BUILD_ROOT/*) echo $path|sed s,^$RPM_BUILD_ROOT,,;;
  esac
} # RemoveRBR


EmitTmpl_aux()
  # in: $sp*   - results from ParseSpec()
  #     $opt_h - html link to "home"
{
echo "<html>
<head>
<title>Package $spName</title>
</head>
<body>
$opt_h
<h1>$spName</h1>
<table>
<!-- It is important that there is only _one_ line per entry -->
<!--!name-->       <tr><td>Name:</td><td>$spName</td></tr>
<!--!summary-->    <tr><td>Summary:</td><td>$spSummary</td></tr>
<!--!url-->        <tr><td>URL:</td><td><a href=\"$spURL\">$spURL</a></td></tr>
<!--!vendor-->     <tr><td>Vendor:</td><td>$spVendor</td></tr>
<!--!version-->    <tr><td>Version:</td><td>$spVersion</td></tr>
<!--!release-->    <tr><td>Release:</td><td>$spRelease</td></tr>
<!--!description--><tr><td>Description:</td><td>$spDescription</td></tr>
</table>
<p>
<!--!adoc-->
<!--!arem-->
</body>
</html>
"
} # EmitTmpl_aux


EmitTmpl_man()
  # in: $sp*   - results from ParseSpec()
  #     $opt_h - html link to "home"
  #     $opt_l - doc directory name
{
  local dir=`RemoveRBR $opt_l`

echo "<html>
<head>
<title>Mandatory docs for $spName</title>
</head>
<body>
$opt_h
<h3>$dir</h3>
<p>
<!--!mdoc-->
<!--!mrem-->
</body>
</html>
"
} # EmitTmpl_man


EmitTmpl_ex()
  # in: $sp*   - results from ParseSpec()
  #     $opt_h - html link to "home"
  #     $opt_l - doc directory name
{
  local dir=`RemoveRBR $opt_l`

echo "<html>
<head>
<title>Examples for $spName</title>
</head>
<body>
$opt_h
<h3>$dir</h3>
<p>
<!--!edoc-->
<!--!erem-->
</body>
</html>
"
} # EmitTmpl_ex


EmitTmpl_sum()
  # in: $opt_o - filename of output
{
echo "<html>
<head>
<title>Package Summary</title>
</head>
<h3>Package Summary for instance '$l_prefix':</h3>
<p>
<body>
<table>
<!--!sdoc-->
</table>
<!--!srem-->
</body>
</html>
"
} # EmitTmpl_sum


EmitTemplate()
  # in : $1 - name/filename of template
  #      $2 - filename of output
{
  local tmpl=$1
  local oFile=$2

  case "$tmpl" in
       odoc_aux) EmitTmpl_aux >$oFile;;
       odoc_man) EmitTmpl_man >$oFile;;
	odoc_ex) EmitTmpl_ex  >$oFile;;
       odoc_sum) EmitTmpl_sum >$oFile;;
              *) if   [ "$tmpl" != "$oFile" ]
	         then cp $tmpl $oFile
		 else true
		 fi;;
  esac
} # EmitTemplate


OdocInf()
  # in : $1     - id of section
  #      $opt_I - path to odoc.inf
{
  local section=$1

  # must be specified
  if   [ -z "$opt_I" ]
  then echo "$myName: position of 'odoc.inf' unknown (-I)"
       exit 1
  fi
  # but existence is optional, as well as the existence of the section
  [ -f "$opt_I" ] || return 0
  sed -n '/^<section id="'$section'">/{
      :a
      n;/^<\/section>/q;p;ba
  }' <$opt_I
} # OdocInf


InsertFile()
  # in : $1 - in-/output file
  #      $2 - insert point (tag for <!--!tag-->
  #      $3 - file to insert
{
  sed "/<!--!$2-->/r $3" <$1 >$1.tmp && mv $1.tmp $1
} # InsertFile


InsertSection()
  # in : $1 - in-/output file
  #      $2 - section/insert point
{
  local ioFile=$1
  local section=$2
  local tmpFile=$TMPDIR/odoc_is$$

  OdocInf $section >$tmpFile
  InsertFile $ioFile $section $tmpFile
  rm $tmpFile
} # InsertSection


InsertDirList()
  # in : $1 - in-/output filename
  #      $2 - insert point in template and
  #           odoc.inf section with additional file infos
  #      $3 - name of directory
{
  local ioFile=$1
  local section=$2
  local dir=$3
  local tmpFile=$TMPDIR/odoc_idl$$
  local tmpiFile=$TMPDIR/odoci_idl$$

  if   [ ! -d "$dir" ]
  then echo "$myName: dir '$dir' not found"
       exit 1
  fi
  rm -f $tmpFile $tmpiFile
  OdocInf $section >$tmpiFile
  [ -s $tmpiFile ] || rm -f $tmpiFile
  echo "<table>" >$tmpFile
  (cd $dir || exit 1
   ls -1 | grep -v "index.html" |
   while read file; do
       val=
       if   [ -r "$tmpiFile" ]
       then val=`egrep "^$file " $infoFile|sed "s,$file ,,"`
       fi
       echo "<tr><td><a href=\"$file\">$file</a></td><td>$val</td></tr>"
   done
  ) >>$tmpFile || { rm -f $tmpFile $tmpiFile; exit 1; }
  echo "</table>" >>$tmpFile
  InsertFile $ioFile $section $tmpFile
  rm -f $tmpFile $tmpiFile
} # InsertDirList


Summary()
  # in : $1      - in-/output filename
  #      $2      - insert point in template
  #      $docDir - %{l_docdir}
{
  local ioFile=$1
  local section=$2
  local tmpFile=$TMPDIR/odoc_s$$
  local pkg pkgDocDir pkgDocIndex
  local moreInfo

  openpkg rpm --queryformat "%{NAME}\n<td>%{VERSION}</td><td>%{RELEASE}</td><td> : %{SUMMARY}</td></tr>\n" -qa |
  while read pkg; do
      pkgDocDir=$docDir/$pkg
      pkgDocIndex=$pkgDocDir/index.html
      if   [ -d $pkgDocDir ]
      then echo -e "$pkg <tr><td><a href=\"$pkgDocIndex\">$pkg</a></td>\c"
      else echo -e "$pkg <tr><td>$pkg</td>\c"
      fi
      read -r moreInfo
      echo "$moreInfo"
  done |
  sort | sed 's/[^ ][^ ]* //' >$tmpFile
  InsertFile $ioFile $section $tmpFile
  rm -f $tmpFile
} # Summary

#
# --------------------------------- MAIN --------------------------------------
#

myFullName=$0
myName=`basename $0`

l_prefix=@l_prefix@

## does a faster implementation (e.g. in perl) exist ?
#if   [ -x "$l_prefix/libexec/openpkg-tools/$myName.pl" ]
#then exec $l_prefix/libexec/openpkg-tools/$myName.pl "$@"
#fi

[ -z "$TMPDIR" ] || [ ! -d "$TMPDIR" ] && TMPDIR=/tmp
docDir=$l_prefix/doc
opkgDocDir=$l_prefix/share/openpkg/docs
opkgDocIndex=$opkgDocDir/index.html

opt_t=
opt_w=
opt_i=
opt_I=
opt_r=
opt_l=
opt_L=
opt_h=
opt_o=
opt_R=
opt_a=
opt_m=
opt_e=
opt_s=
opt_v=
opt_F=
#FIXME getopts
set -- `getopt "t:w:iI:r:l:Lh:o:RamesvF" "$@"`
while [ -n "$1" ]
do  case "$1" in
         -t) opt_t=$2; shift; shift;;
         -w) opt_w=$2; shift; shift;;
         -i) opt_i=1; shift;;
	 -I) opt_I=$2; shift; shift;;
	 -r) opt_r=$2; shift; shift;;
         -l) opt_l=$2; shift; shift;;
	 -L) opt_L=1; shift;;
	 -h) opt_h=$2; shift; shift;;
	 -o) opt_o=$2; shift; shift;;
	 -R) opt_R=1; shift;;
	 -a) opt_a=1; shift;;
	 -m) opt_m=1; shift;;
	 -e) opt_e=1; shift;;
	 -s) opt_s=1; shift;;
	 -v) opt_v=1; shift;;
	 -F) exit 1;;
         --) shift; break;;
          *) echo "$myName: unknown option: '$1'"
             exit 1;;
    esac
done

if   [ -n "$opt_v" ]
then V=echo
else V=:
fi

$V ""
$V "$myName: parameter(s) :" "$@"

spec=$1
if   [ -n "$2" ]
then echo "$myName: too many parameters"
     exit 1
fi

if   [ -n "$opt_a$opt_m$opt_e$opt_s" ]
then if   [ -n "$opt_t$opt_w$opt_i$opt_I$opt_r$opt_l$opt_L$opt_h$opt_o$opt_R" ]
     then echo "$myName: no option except -v allowed whith -a, -m, -e and -s"
          exit 1
     fi
fi
if   [ -n "$opt_a$opt_m$opt_e" ] && [ -n "$opt_s" ]
then echo "$myName: -a, -m, and -e must not be specified together with -s"
     exit 1
fi
if   [ -n "$opt_s" ] && [ -n "$spec" ]
then echo "$myName: <spec> must not be specified with -s"
     exit 1
fi
if   [ -z "$opt_s" ] && [ -z "$spec" ]
then echo "$myName: missing <spec>"
     exit 1
fi

$V ""
$V "TMPDIR:.........'$TMPDIR'"
$V "opkgDocDir:.....'$opkgDocDir'"
$V "opkgDocIndex:...'$opkgDocIndex'"
$V "docDir:.........'$docDir'"

if   [ -n "$opt_s" ]
then opt_t=odoc_sum
     opt_w=sdoc
     opt_o=$opkgDocIndex
     $V "opt_t:..........'$opt_t'"
     $V "opt_w:..........'$opt_w'"
     $V "opt_o:..........'$opt_o'"
     EmitTemplate $opt_t $opt_o || exit 1
     Summary $opt_o $opt_w
     exit
fi

sourceDir=`dirname $spec`
specB=`basename $spec`
pkgName=`basename $spec .spec`
#    does not exist   || does not end with ".spec"
if   [ ! -f "$spec" ] || [ "$pkgName" = "$specB" ]
then echo "$myName: bad value for <spec> : '$spec'"
     exit 1
fi

if   [ "$opt_a$opt_m$opt_e" -gt 1 ]
then ( [ -n "$opt_v" ] && v="-v" || v=
       [ -n "$opt_a" ] && { $myFullName $v -a $spec || exit 1; }
       [ -n "$opt_m" ] && { $myFullName $v -m $spec || exit 1; }
       [ -n "$opt_e" ] && { $myFullName $v -e $spec || exit 1; }
       true
     )
     exit
fi
if   [ -n "$opt_a" ]
then opt_t=odoc_aux
     opt_w=adoc
     opt_l=$l_prefix/doc/$pkgName
     opt_L=1
     opt_R=1
     opt_h=../../../..$l_prefix/share/openpkg/docs/index.html
     opt_o=$l_prefix/doc/$pkgName/index.html
elif [ -n "$opt_m" ]
then opt_t=odoc_man
     opt_w=mdoc
     opt_l=$l_prefix/share/$pkgName/docs
     opt_R=1
     opt_o=$l_prefix/share/$pkgName/docs/index.html
elif [ -n "$opt_e" ]
then opt_t=odoc_ex
     opt_w=edoc
     opt_l=$l_prefix/share/$pkgName/examples
     opt_R=1
     opt_o=$l_prefix/share/$pkgName/examples/index.html
elif [ -z "$opt_t" ]
then echo "$myName: -t missing"
     exit 1
fi

[ -z "$opt_I" ] && opt_I=$sourceDir/odoc.inf
[ -z "$opt_o" ] && opt_o=$opt_t

if   [ -n "$opt_h" ]
then opt_h="<a href=\"$opt_h\">home</a>"
fi

pkgDocDir=$docDir/$pkgName
if   [ -n "$opt_R" ]
then if   [ -z "$RPM_BUILD_ROOT" ]
     then echo "$myName: RPM_BUILD_ROOT not set !"
	  exit 1
     fi
     pkgDocDir=`PrependRBR $pkgDocDir`
     [ -n "$opt_l" ] && opt_l=`PrependRBR $opt_l`
     [ -n "$opt_o" ] && opt_o=`PrependRBR $opt_o`
fi
if   [ ! -d "$pkgDocDir" ]
then echo "$myName: package's doc dir has to exist : '$pkgDocDir'"
     exit 1
fi

if   [ -n "$opt_L" ]
then if   [ -d "$pkgDocDir/../../share/$pkgName/docs" ]
     then ln -s ../../share/$pkgName/docs $pkgDocDir
     fi
     if   [ -d "$pkgDocDir/../../share/$pkgName/examples" ]
     then ln -s ../../share/$pkgName/examples $pkgDocDir
     fi
fi

eval `ParseSpec $spec` || exit 1

$V ""
$V "spec:...........'$spec'"
$V "sourceDir:......'$sourceDir'"
$V "pkgName:........'$pkgName'"
$V "pkgDocDir:......'$pkgDocDir'"
$V ""
$V "opt_t:..........'$opt_t'"
$V "opt_w:..........'$opt_w'"
$V "opt_l:..........'$opt_l'"
$V "opt_L:..........'$opt_L'"
$V "opt_R:..........'$opt_R'"
$V "opt_h:..........'$opt_h'"
$V "opt_o:..........'$opt_o'"
$V ""
$V "spName:.........'$spName'"
$V "spSummary:......'$spSummary'"
$V "spURL:..........'$spURL'"
$V "spVendor:.......'$spVendor'"
$V "spVersion:......'$spVersion'"
$V "spDescription:..'$spDescription'"

EmitTemplate $opt_t $opt_o || exit 1

[ -n "$opt_l" ] && { InsertDirList $opt_o $opt_w $opt_l || exit 1; }
[ -n "$opt_i" ] && { InsertSection $opt_o $opt_w        || exit 1; }
[ -n "$opt_r" ] && { InsertFile    $opt_o $opt_w $opt_r || exit 1; }

true
