#!/usr/bin/python
import sys, os
if os.sep + 'dosage' in os.path.abspath(sys.argv[0]):
    sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))

import dosage.modules
import csv
import re

'''
This tool builds a list of all comic modules dosage supports, gets some support
data from a CSV table and generates a nice HTML table to compare Dosage against
other webcomic aggregators.
'''

def constructRow(header, dataDict, count, url = None):
    row = []
    url = url or dataDict['URL']
    for x in header:
        celldata = dataDict[x]
        if celldata.split()[0] == '-':
            cellclass = 'bad'
        else:
            cellclass = 'good'
            if dataDict["broken"] != 'yes':
                count[x].add(celldata)

        if x == 'Name':
            if dataDict["broken"] == 'yes':
                cellclass = 'bad'
                count['broken'].add(celldata)
            if url != None:
                celldata = '<a href="%s">%s</a>' % (url, celldata)
        row.append((cellclass, celldata))
    return row


def simpleTable(datarows, headerrows = [], footerrows = []):
    html = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
    <html><head><title>Dosage Comparison</title>
    <script src="sortable.js"></script>
    <meta http-equiv="Content-Type" value="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="compare-table.css">
    </head><body><p>For easier reading this table is color coded. For the first
    column green fields show that this comic was found on the net the last time
    someone checked, red means the comic seems to have disappered. For all
    other columns green shows a supported comic and red an unsupported
    comic.</p>
    <table class="sortable" id="comparison"><thead>
    '''
    for row in headerrows:
        html += '<tr><th>' + '</th><th>'.join(row) + "</th></tr>\n"
    html += "</thead><tfoot>\n"
    for row in footerrows:
        html += '<tr><th>' + '</th><th>'.join(row) + "</th></tr>\n"
    html += "</tfoot><tbody>\n"
    for row in datarows:
        html += '<tr>' + ''.join(['<td class="%s">%s</td>' % x for x in row]) + "</tr>\n"
    html += "</tbody></table></body>"
    return html

def main():
    base = os.path.splitext(sys.argv[0])[0]
    csvdata = csv.DictReader(open(base + ".csv", "rb"), dialect='excel-tab')
    supported = {}
    unsupported = []
    for row in csvdata:
        if row['Dosage'].split()[0] != '-':
            for strip in row['Dosage'].split(','):
                supported[strip] = row.copy()
                supported[strip]['Dosage'] = strip
        else:
            unsupported.append(row)
    header = [x for x in csvdata.fieldnames if x not in ('URL', 'broken')]

    counters = {}
    for x in csvdata.fieldnames:
        counters[x] = set()

    rows = []
    notfound = []
    for moduleName in dosage.modules.items(dosage.modules.__path__[0]):
        module = dosage.modules.get(moduleName)
        extradata = supported.pop(moduleName, None)
        if extradata:
            try:
                url = module.latestUrl
            except:
                print "WARNING: %s cannot get latest URL!" % (moduleName)
                url = getattr(module, 'baseUrl', None)
            rows.append(constructRow(header, extradata, counters, url))
        else:
            notfound.append(moduleName)
    print "The following Dosage modules are not in the CSV table: " + " ".join(notfound)
    print "The following Dosage modules are in the CSV table but not in Dosage: " + " ".join(supported)

    # At least add the rows with errors to the table
    for module in supported:
        supported[module]['Dosage'] = '- (was %s)' % (module)
        rows.append(constructRow(header, supported[module], counters))

    for module in unsupported:
        rows.append(constructRow(header, module, counters))

    footer = [str(len(counters[x])) for x in header]
    footer[0] += ' (+ %i broken)' % (len(counters['broken']))

    deltags = re.compile(r'<[^<>]+>')
    rows.sort(cmp = lambda x,y: cmp(deltags.sub("", x[0][1].lower()), deltags.sub("", y[0][1].lower())))

    f = open(base + '.html', 'w')
    try:
        f.write(simpleTable(rows, [header], [footer]))
    finally:
        f.close()

if __name__ == '__main__':
    main()
