#!/bin/sh
# Builds HTML5 insert for LED-lighting page from database of review files.
# Note that this can be optimised for HTML5 size rather than XHTML compliance.

# Args are attr files.

# TODO: move the hreview markup from the table to the full-text
# to ensure that all the text is always visible.
# Possibly re-insert the summary to that effect also.
# Possibly spit out separate indexable pages.

# Depends on a number of CSS files:
#   * For 'deep green' marking:
#     img/css/deepgreen-20170605.css
#   * For autocollapsing comments:
#     img/css/autocollapse-20160620.css
#   * For table styling:
#     img/css/table-20170622.css
#   * For 'dopt' items to be hidden on very narrow screens:
#     img/css/dopt-20180522.min.css
#   * For tal/tac/tar text-align left/centre/right:
#     img/css/ta-20181208.css

# Location of DB.
LEDDB=db.LED-lighting

# Output is $OUT
OUT=.work/inc/.LED-lighting.html.inc

# Compute this and previous years.
YEARTHIS=`date '+%Y'`
YEARPREV=`expr $YEARTHIS - 1`

# Prevent concurrent build attempts with this lockfile.
# Since this should always be fast we can remove a fossil lock after minutes.
LOCKFILE=.work/.LED-lighting.html.lock
if lockfile -r 1 -l 120 $LOCKFILE; then
    : lock successfully taken
else
    echo Already running...
    exit 1
fi
# Upon exit, remove lockfile.
trap "{ rm -f $LOCKFILE ; exit 0; }" 0 2 3 15

# Could be awk or gawk...
AWK=awk

echo "INFO: rebuilding $OUT from ${LEDDB} contents..." 1>&2

# Example .attr.txt file format: lines may be re-ordered.
# No entry breaks across lines or contains '|' other than as separator.
#categorymajor|Non-Mains
#categoryminor|night-light
#reviewrating|5
#reviewdate|2012/06/23
#fitting|none
#reviewer|Damon Hart-Davis
#fullname|Home-brew rechargeable night-light
#efficacy|100
#brand|DHD
#mpn|HBID
#image|img/LED.jpg


# Count of devices/entries.
ITEMCOUNT="`echo ${LEDDB}/*.attr.txt | awk '{print NF}'`"

# Sort items into order for the table(s).
TABLEORDER=.work/.LED-lighting.html.order
rm -f ${TABLEORDER}
for f in ${LEDDB}/*.attr.txt;
    do
        ${AWK} -F'|' < $f '{ n[$1]=$2; }
        END { print \
            n["categorymajor"] "|" \
            n["categoryminor"] "|" \
            n["reviewrating"] "|" \
            n["reviewdate"] "|" \
            n["fitting"] "|" \
            n["fullname"] "|" \
            n["reviewer"] "|" \
            n["efficacy"] "|" \
            n["defunct"] "|" \
            n["brand"] "|" \
            n["mpn"] "|" \
            n["image"] "|" \
            name; }' \
        name=`basename $f .attr.txt`
    done | sort -t'|' -k1,1 -k5,5 -k3,3nr -k4,4r > ${TABLEORDER}

#cat ${TABLEORDER}

# Make tables... (start temporary file)
# Table contains Product and (short-form) Review (could become UserReview).
${AWK} -F'|' -v ITEMCOUNT=$ITEMCOUNT< ${TABLEORDER} > ${OUT}.tmp '
        BEGIN {
            print "<div class=\"cb doptsml tac\" style=padding:1ex><table class=\"fullwctbl tb1\"><caption>LED Reviews ("ITEMCOUNT")</caption>";
        }
        {
        categorymajor = $1;
        categoryminor = $2;
        reviewrating = $3;
        reviewdate = $4;
        fitting = $5;
        fullname = $6;
        reviewer = $7;
        efficacy = $8;
        defunct = $9;
        brand = $10;
        mpn = $11;
        image = $12; # If present, full URL or img/... path.
        name = $NF; # Always last field.

        if(categorymajor != prevcategorymajor) {
            print "<tr><th style=font-variant:small-caps>" categorymajor "<th style=width:33%>Photo<th>Score /5<th>lm/<wbr>W<th class=summary>Summary<th class=dopt>Review";
            prevcategorymajor = categorymajor;
            }

        # Insert cross-head for change of fitting.
        # Must not fail horribly if no description text.
        if(fitting != oldfitting) {
            print "<tr class=dopt><th colspan=2>Fitting: " fitting "</th>"
            print "<th colspan=4>";
            descfile = LEDDB "/fittings/" fitting ".txt";
            while(0 < (status = (getline line < descfile))) {
                if("" == line) { continue; }
                print line;
            }
            close(descfile);
            print "</th>";
            oldfitting = fitting;
        }

        # Write data line.
        # Aggressively omit optional closing tags to save page weight.
        printf("<tr id=r-"name" itemprop=about itemscope itemtype=http://schema.org/Product>");
        print "<td";
             if(defunct != "") { print " style=text-decoration:line-through"; }
             print "><span itemprop=\"name description\">" fullname "</span>";
             if(defunct != "") { print "(" defunct ")"; }

        # Inject a whole bunch of invisible boilerplate into first cell...
        # By default no offers.
        print "<meta itemprop=offers itemscope itemtype=http://schema.org/Offer itemref=NoOffer content=\"\">"
        # Use the MPN if we have one.
        if("" != mpn) { print "<meta itemprop=mpn content=\""mpn"\">"; }
        # Invent a unique SKU to silence one GSC warning.
        print "<meta itemprop=sku content=LED-"name">";
        # Indicate the brand where extant and known.
        if("" != brand) { print "<span itemprop=brand itemscope itemtype=http://schema.org/Brand><meta itemprop=name content=\""brand"\"></span>"; }
        # Create a category.
        print "<meta itemprop=category content=\""categorymajor" / "categoryminor" / "fitting"\">";
        # Include image link if present (and a recognised format).
        if("" != image) {
            if(1 == index(image, "img/")) {
                print "<link href=//STATIC.earth.org.uk/"image" itemprop=image>"
            } else if(1 == index(image, "http")) {
                print "<link href="image" itemprop=image>"
            }
        }

        # Image (thumbnail nominally).
        print "<td>"
        if("" != image) {
            print "<IMG src=\""image"\" class=\"respsml\" />";
        }

        # Review rating, marked 'deepgreen' for the very best items.
        if(reviewrating > 4) { rc = " deepgreen"; } else { rc = ""; }
        print "<td class=\"rating tac" rc "\" style=font-size:larger itemprop=aggregateRating itemscope itemtype=http://schema.org/AggregateRating><span id=Rating-"name"><span itemprop=ratingValue>" reviewrating "</span><meta itemprop=reviewCount content=1></span>";

        if(efficacy != "") {
            if(efficacy >= 60) {
                print "<td class=\"deepgreen tac\"";
            } else {
                print "<td class=tac";
            }
            print "itemprop=additionalProperty itemscope itemtype=http://schema.org/PropertyValue>";
            print "<span itemprop=value>" efficacy "</span>";
            print "<meta itemprop=unitCode content=B61>";
        } else {
            print "<td>";
        }

        # Summary: include summary text if any then link to section.
        # Must not fail horribly if no summary text.
        print "<td class=tal itemprop=review itemscope itemtype=http://schema.org/Review>"
        print "<span itemprop=reviewBody>";
        summaryfile = LEDDB "/" name ".summary.html.txt";
        while(0 < (status = (getline line < summaryfile))) {
            if("" == line) { continue; }
            print line;
        }
        close(summaryfile);
        print "</span>";
        # ID for href should not need quotes.
        print "<a href=#" name ">More...</a>";
        # Invisible content for Review (visible elsewhere on the page).
        if(("Damon Hart-Davis" == reviewer) ||
           ("Damon Hart-Davis et al" == reviewer)) {
            # If author is DHD link to the page author.
            print "<meta itemprop=author itemscope itemtype=http://schema.org/Person itemref=pgAuthor content=\"\">";
        } else {
            # If multiple authors separated by commas,
            # insert multiple separate entries.
            split(reviewer, a, ",");
            for(i in a) {
                print "<span itemprop=author itemscope itemtype=http://schema.org/Person><span itemprop=name>"a[i]"</span></span>";
                }
            }
        print "<meta itemprop=datePublished content="reviewdate">";
        print "<meta itemprop=reviewRating itemscope itemtype=http://schema.org/AggregateRating itemref=Rating-"name" content=\"\">"

        # Review date.
        # Just show year, and make it stand out if this year or last.
        reviewyear = substr(reviewdate, 1, 4);
        rystyle = "";
        if(('$YEARTHIS' == reviewyear) || ('$YEARPREV' == reviewyear)) {
            rystyle = " style=font-size:larger";
            }
        print "<td class=dopt "rystyle">"
        print reviewyear;
    }
    END { print "</table></div>"; }' \
    LEDDB=$LEDDB

# Example output data line in table WITH hreview.
#<tr class="hreview">
#<td class="item"><span class="fn">LEDON 10W "warm" white bayonet</span></td>
#<td>B22</td>
#<td class="deepgreen"><span class="rating">5</span></td>
#<td><span class="dtreviewed">2012/01/01<span class="value-title" title="2012-01-01"></span></span></td>
#<td class="summary">
#<a href="http://gallery.hd.org/_c/light/_more2012/_more01/low-energy-LED-10W-very-warm-white-2700K-B22-bayonet-240V-mains-lamp-600lm-1-million-operations-9-DHD.jpg.html"><img src="img/LEDON10W.jpg" align="right" width="32" height="32" border="0" alt="LEDON 10W 600lm 2700K 240V B22 bayonet" title="LEDON 10W 600lm 2700K 240V B22 bayonet" /></a>
#Energy Saving Trust approved and doing sterling work in our bathroom where a 7W lamp was not quite enough to read or see all the grime!
#<a href="#LEDON10W">More...</a>
#</td>
#<td class="reviewer">Damon Hart-Davis</td>
#</tr>

# Insert full-text descriptions in file.
${AWK} -F'|' < ${TABLEORDER} >> ${OUT}.tmp '{
        categorymajor = $1;
        categoryminor = $2;
        reviewrating = $3;
        reviewdate = $4;
        fitting = $5;
        fullname = $6;
        reviewer = $7;
        efficacy = $8;
        defunct = $9;
        brand = $10;
        mpn = $11;
        image = $12;
        name = $NF; # Always last field.

        if(categorymajor != prevcategorymajor) {
            # Insert heading with anchor.
            print "<h3 id=\"" categorymajor "\">Category: " categorymajor "</h3>";
            prevcategorymajor = categorymajor;
            }

        # Heading...
        # ID should not need quoting.
        print "<section class=\"cb conl\">"
        print "<h4 id=" name ">" fullname " (" reviewrating "/5) " fitting"</h4>";

        # Insert date and reviewer at start of each review.
        print "(" reviewdate ", " reviewer ") ";

        # Must not fail horribly if no text.
        reviewfile = LEDDB "/" name ".html.txt";
        while(0 < (status = (getline line < reviewfile))) {
            if("" == line) { continue; }
            print line;
        }
        close(reviewfile);

        # Close section.
        print "</section>"
        }' \
    LEDDB=$LEDDB

# Append default no-offers item.
#printf "<span itemprop="offers" itemscope itemtype="http://schema.org/Offer"><meta itemprop="availability" content="http://schema.org/SoldOut" /><meta itemprop="price" content="0" /><meta itemprop="priceCurrency" content="GBP" /><link href="https://www.futurebuild.co.uk/" itemprop="url"><meta itemprop="validFrom" content="2020-03-03" /></span>" >> ${OUT}.tmp
printf "<span id=NoOffer><meta itemprop=availability content=http://schema.org/SoldOut><meta itemprop=price content=0><meta itemprop=priceCurrency content=GBP><link href=# itemprop=url><meta itemprop=priceValidUntil content=2000-01-01></span>" >> ${OUT}.tmp


# Move temporary file into place.
mv -f ${OUT}.tmp ${OUT}


rm ${TABLEORDER}
