#!/bin/sh
# mkhie.sh - generate hie.yaml for haskell-language-server
# usage: mkhie.sh > hie.yaml

GITINFO=$(git describe --always --dirty 2>/dev/null || echo "(unknown)")

echo '# hie.yaml for haskell-language-server'
echo "# generated by mkhie.sh as of $GITINFO; do not edit"
echo 'cradle:'
echo '  cabal:'

# Read cabal.project and find all the *.cabal files
expand < cabal.project | awk '
   /^ *$/ { next; }
   /^packages:/ { look = 1; next; }
   /^[a-zA-Z]/ { look = 0; next; }
   /^ / && look { print $1; }
' | awk '
   /\.cabal$/ { print ".", $1; next; }
   { system(sprintf("cd %s && printf \"%s \" && ls *.cabal", $1, $1)); }
' | (
    # Read each foo.cabal
    while read -r DIR FN; do
        #echo "$FN" 1>&2
        expand < "$DIR/$FN" | awk '
           BEGIN { pkg = ""; ty = ""; }

           /^[Nn]ame: / { pkg = $2; next; }
           /^[Cc]ommon / { ty="common"; name=$2; next; }
           /^[Bb]enchmark / { ty="bench"; name=$2; next; }
           /^[Ll]ibrary$/ { ty="lib"; name=""; next; }
           /^[Ll]ibrary / { ty="lib"; name=$2; next; }
           /^[Ee]xecutable / { ty="exe"; name=$2; next; }
           /^[Tt]est-suite / { ty="test"; name=$2; next; }
           /^[A-Za-z]/ { ty=""; next; }

           /^  *[Hh]s-source-dirs:/ { source($2); next; }
           /^  *[Ii]mport:/ {
               $1="";
               delete imports;
               nimports = split($0, imports, ",");
               for (i=1;i<=nimports;i++) {
                   sub("^ +", "", imports[i]);
                   sub(" +$", "", imports[i]);
                   if (imports[i] in commons) {
                       source(commons[imports[i]]);
                   }
               }
               next;
           }

           function source(srcdir) {
               if (ty == "common") {
                   commons[name] = srcdir;
                   return;
               }
               if (!name) {
                   name = pkg;
               }
               if (!ty) {
                   printf "# WARNING: no component for %s in %s\n", srcdir, ty;
                   return;
               }
               printf "    - path: \"%s/%s\"\n", dir, srcdir;
               printf "      component: \"%s:%s:%s\"\n", pkg, ty, name;
           }
       ' "dir=$DIR"
    done
)
