#!/usr/bin/env python3

from datetime import datetime
import sys
import argparse

import reflectrpc
import reflectrpc.cmdline

def format_type(typename):
    if not len(typename):
        return typename

    if typename[0].isupper():
        return '<a href="#type-%s">%s</a>' % (typename, typename)

    return typename

parser = reflectrpc.cmdline.build_cmdline_parser("Generate documentation from a running ReflectRPC service")

# Add our program-specific arguments
parser.add_argument("outfile", metavar='OUTFILE', type=str, help="Output file")

args = parser.parse_args()
client = reflectrpc.cmdline.connect_client(args)

(service_description, functions, custom_types) = reflectrpc.cmdline.fetch_service_metainfo(client)

f = open(args.outfile, "w")

style = """
<style type="text/css">
body {
    font-family: Verdana, Geneva, sans-serif;
    margin: 3em;
}

a {
    color: #4078c0;
}

a:link {
    text-decoration: none;
}

a:visited {
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

a:active {
    text-decoration: underline;
}

h1 {
    border-bottom: 1px solid #ddd;
}

h2 {
    border-bottom: 1px solid #ddd;
}

h3 {
    margin-bottom: 0;
}

.description {
    color: #888;
}

.typename {
    font-style:italic;
}

table.withborders {
    border-spacing: 0;
    border-top: 1px solid #ddd;
    border-right: 1px solid #ddd;
}

table.withborders th {
    border-left: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    padding: 0.5em;
    background-color: #eee;
}

table.withborders td {
    border-left: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    padding: 0.5em;
}
</style>
"""

title = service_description['name'] + ' - ReflectRPC Service Documentation'

f.write('<!DOCTYPE html>\n')
f.write('<html>\n<head>\n<meta charset="UTF-8">\n')
f.write('<title>%s</title>\n%s</head>\n<body>\n' % (title, style))

f.write('<h1>ReflectRPC Service Documentation</h1>\n')
f.write('<table>')
f.write('<tr><td>Service Name:</td><td>%s</td></tr>\n' % (service_description['name']))
f.write('<tr><td>Version:</td><td>%s</td></tr>\n' % (service_description['version']))
f.write('<tr><td>Description:</td><td>%s</td></tr>\n' % (service_description['description']))
f.write('<tr><td>&nbsp;</td><td>&nbsp;</td></tr>\n')

if args.host.startswith('unix://'):
    f.write('<tr><td>Generated from:</td><td>%s</td></tr>\n' % (args.host))
else:
    f.write('<tr><td>Generated from:</td><td>%s:%d</td></tr>\n' % (args.host, args.port))

f.write('<tr><td>Generated at:</td><td>%s (UTC)</td></tr>\n' % (str(datetime.utcnow().replace(microsecond=0))))
f.write('<tr><td>Generated by:</td><td>ReflectRPC (rpcdoc) %s</td></tr>\n' % (reflectrpc.version))
f.write('</table>')

f.write('<h2>Types</h2>\n')
for t in custom_types:
    if t['type'] == 'enum':
        f.write('<a name="type-%s"></a>\n' % (t['name']))
        f.write('<h3>%s (Enum)</h3>\n' % (t['name']))
        f.write('<div class="description">%s</div>\n' % (t['description']))
        f.write('<p>Enum values:</p>')
        f.write('<table class="withborders">')
        f.write('<tr><th>Int value</th><th>String value</th><th>Description</th></tr>')
        for value in t['values']:
            f.write('<tr><td>%d</td><td>%s</td><td>%s</td></tr>\n' % (value['intvalue'], value['name'], value['description']))
        f.write('</table>')
    elif t['type'] == 'hash':
        f.write('<a name="type-%s"></a>\n' % (t['name']))
        f.write('<h3>%s (Named Hash)</h3>\n' % (t['name']))
        f.write('<div class="description">%s</div>\n' % (t['description']))
        f.write('<p>Fields of this type:</p>')
        f.write('<table class="withborders">')
        f.write('<tr><th>Name</th><th>Type</th><th>Description</th></tr>')
        for field in t['fields']:
            f.write('<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n' % (field['name'], format_type(field['type']), field['description']))
        f.write('</table>')
    else:
        f.write('<p>Unknown class of custom type: %s</p>\n' % (t['type']))

f.write('<h2>Functions</h2>\n')
for func_desc in functions:
    paramlist = [param['name'] for param in func_desc['params']]
    paramlist = ', '.join(paramlist)

    f.write('<a name="func-%s"></a>\n' % (func_desc['name']))
    f.write("<h3>%s</h3>\n" % (func_desc['name']))
    f.write('<div class="description">%s(%s) - %s</div>' % (func_desc['name'], paramlist, func_desc['description']))
    f.write('<p>Parameters:</p>')
    f.write('<table>')
    for param in func_desc['params']:
        f.write('<tr><td>%s:</td><td><div class="typename">%s</div></td><td>-</td><td class="description">%s</td></tr>\n' % (param['name'], format_type(param['type']), param['description']))
    f.write('</table>')

    f.write('<p>Returns: <span class="typename">%s</span> - <span class="description">%s</span></p>\n' % (format_type(func_desc['result_type']), func_desc['result_desc']))

f.write('</body>\n</html>')
f.close()
