#!/bin/bash -p
###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2016 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under 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. Please see the file LICENSE-GPL for details.
#
# Web Page: http://brltty.com/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

set -e
shopt -s nullglob

defaultArchiveName="brltty-dos"
defaultInstallDirectory="BRLTTY"

. "`dirname "${0}"`/../prologue.sh"
addProgramOption a string.name archiveName "specify archive name" "${defaultArchiveName}"
addProgramOption i string.directory installDirectory "specify installation directory on target system" "${defaultInstallDirectory}"
addProgramOption o flag overwriteArchive "overwrite existing archive"
addProgramOption s flag invokeShell "invoke interactive shell to inspect/modify result"
addProgramParameter source sourceDirectory "top-level directory of source tree"
parseProgramArguments "${@}"

[ -n "${archiveName}" ] || archiveName="${defaultArchiveName}"
[ -n "${installDirectory}" ] || installDirectory="${defaultInstallDirectory}"

[ -n "${sourceDirectory}" ] || sourceDirectory="."
verifyInputDirectory "${sourceDirectory}" || semanticError
sourceDirectory="$(resolveDirectory "${sourceDirectory}")"

archivePath="${initialDirectory}/${archiveName}.zip"
[ ! -e "${archivePath}" ] || {
   "${overwriteArchive}" ] || semanticError "archive already exists: ${archivePath}"
   rm -f -r "${archivePath}"
}

function convertTextFile {
   local file="${1}"

   unix2dos -q -o "${file}"
}

function installFile {
   local sourceFile="${1}"
   local targetFile="${2}"

   targetFile="${installDirectory}/${targetFile}"
   local targetDirectory="${targetFile%/*}"
   mkdir -p "${targetDirectory}"
   cp "${sourceFile}" "${targetFile}"
}

function installManualFiles {
   local directory="${1}"

   cd "${directory}/Documents/Manual-BRLTTY"

   local oldFile
   for oldFile in $(find . -type f)
   do
      local newFile="${oldFile}"

      local subdirectory="${oldFile%/*}"
      local name="${oldFile##*/}"

      local extension="${name##*.}"
      name="${name%.*}"

      case "${extension}"
      in
         html)
            sed -r -e 's/"([[:alpha:]]+)(-([[:digit:]]+))?\.html(["#])/"\1\3.htm\4/g' -i "${oldFile}"
            newFile="${subdirectory}/${name/-/}.${extension:0:3}"
            ;;

         txt | htm | doc | pdf);;
         *) continue;;
      esac

      installFile "${oldFile}" "${manualSubdirectory}/${newFile}"
   done
}

needTemporaryDirectory

buildDirectory="${temporaryDirectory}/build"
mkdir -p "${buildDirectory}"

installDirectory="${temporaryDirectory}/intall/${installDirectory}"
mkdir -p "${installDirectory}"
documentSubdirectory="doc"
manualSubdirectory="${documentSubdirectory}/Manual"

cd "${buildDirectory}"
logMessage task "configuring build"
"${sourceDirectory}/cfg-dos" --prefix="${installDirectory}"
logMessage task "building programs"
make -s all
logMessage task "building documentation"
make -s -C Documents
logMessage task "installing files"
make -s install
logMessage task "updating files"

cd "${installDirectory}/bin"
rm brltty-config
mv brltty-trtxt.exe brltrtxt.exe
mv brltty-ttb.exe brlttb.exe
mv brltty-atb.exe brlatb.exe
mv brltty-ctb.exe brlctb.exe
mv brltty-ktb.exe brlktb.exe
mv brltty-tune.exe brltune.exe

cd "${sourceDirectory}/DOS"
installFile cwsdpmi.exe "bin/cwsdpmi.exe"

cd "${sourceDirectory}/Drivers"
name=README
for driverType in Braille Speech
do
   cd "${driverType}"

   for driverName in *
   do
      cd "${driverName}"
      typeset -u driverCode="$(sed -n -e '/^ *DRIVER_CODE *= */s/^.*= *//p' "Makefile.in")"

      for file in "${name}"*
      do
         document="${file/#${name}/${driverCode}}"
         document="${document//./-}"
         installFile "${file}" "${documentSubdirectory}/Drivers/${driverType}/${document}.txt"
      done

      cd ..
   done

   cd ..
done

cd "${sourceDirectory}"
installFile "LICENSE-GPL" "LIC-GPL.txt"
installFile "LICENSE-LGPL" "LIC-LGPL.txt"
installFile "README" "README.txt"
installFile "Documents/README.DOS" "${documentSubdirectory}/DOS.txt"
installFile "Documents/ChangeLog" "${documentSubdirectory}/CHANGES.txt"
installFile "Documents/HISTORY" "${documentSubdirectory}/HISTORY.txt"
installFile "Documents/TODO" "${documentSubdirectory}/TODO.txt"

installManualFiles "${sourceDirectory}"
installManualFiles "${buildDirectory}"

cd "${buildDirectory}"
installFile "Documents/brltty.conf" "etc/brltty.cfg"
installFile "Programs/revision_identifier.h" "REVISION.txt"
sed -e 's/"//g' -i "${installDirectory}/REVISION.txt"

cd "${installDirectory}"
mv share/man .
rm -f -r share
cd man

for source in */*
do
   target="${source/%?/txt}"
   MANWIDTH=80 LC_ALL=C man "${source}" | ul -t dumb | expand | uniq >"${target}"
   rm "${source}"
done

logMessage task "converting text files"
cd "${installDirectory}"
find . -print |
   while read path
   do
      handle="${path#.}"
      [ -n "${handle}" ] || continue

      name="${path##*/}"
      extension="${name##*.}"

      if [ "${name#*.*.}" != "${name}" ]
      then
         logMessage warning "name contains more than one dot: ${handle}"
      elif [ "${name#.}" != "${name}" ]
      then
         logMessage warning "null name: ${handle}"
      elif [ "${name%.}" != "${name}" ]
      then
         logMessage warning "null extension: ${handle}"
      elif [ -f "${path}" ]
      then
         if [ "${extension}" = "${name}" ]
         then
            logMessage warning "file without an extension: ${handle}"
         else
            case "${extension}"
            in
               txt | html | htm | cfg | [tack]t[bi] | h) convertTextFile "${path}";;
               exe | pdf | doc);;
               *) logMessage warning "unexpected file extension: ${handle}";;
            esac
         fi
      elif [ -d "${path}" ]
      then
         if [ "${extension}" != "${name}" ]
         then
            logMessage warning "directory with an extension: ${handle}"
         fi
      else
         logMessage warning "unsupported special file: ${handle}"
      fi
   done

logMessage task "checking for name collisions"
cd "${installDirectory}"
find . -type d -print |
   while read directory
   do
      declare -A shortNames=()

      for longName in $(ls -1 --quote-name --quoting-style=shell "${directory}")
      do
         delimiter="."
         prefix="${longName%${delimiter}*}"

         if [ "${prefix}" = "${longName}" ]
         then
            suffix=""
            delimiter=""
         else
            suffix="${longName:${#prefix}+${#delimiter}}"
         fi

         prefix="${prefix:0:8}"
         suffix="${suffix:0:3}"
         declare -u shortName="${prefix}${delimiter}${suffix}"

         if [ "${#shortNames["${shortName}"]}" -eq 0 ]
         then
            shortNames["${shortName}"]="${longName}"
         else
            logMessage warning "name collision: ${directory#.}: ${shortNames["${shortName}"]} & ${longName}"
         fi
      done
   done

! "${invokeShell}" || {
   logMessage task "invoking shell"
   cd "${installDirectory}"
   "${SHELL:-/bin/sh}" || :
}

logMessage task "creating archive"
cd "${installDirectory}/.."
zip -q -r "${archivePath}" "${installDirectory##*/}"

logMessage task "done"
exit 0
