#!/usr/bin/env python

import os
import sys
import glob
import yaml
import argparse
import datetime
import hashlib
from fcntl import lockf, LOCK_EX, LOCK_NB

from lxml.etree import Element, SubElement, Comment, tostring, CDATA

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument('-f', dest='filepattern', action='store',
                        default='users/*.yaml',
                        help='Pattern of YAML files to process')
    parser.add_argument('-r', dest='privround', action='store_true',
                        default=False,
                        help='Round coordinates to two decimal points for privacy')
    parser.add_argument('-o', dest='outfile', action='store',
                        default='www/developers.kml',
                        help='Where to output the resulting KML file')
    parser.add_argument('-d', dest='dryrun', action='store_true',
                        help='Do not write anything, just do a dry run')

    args = parser.parse_args()

    el_kml = Element('kml')
    el_kml.append(Comment('Generated on %s' % datetime.datetime.today().strftime('%F %T')))
    el_doc = SubElement(el_kml, 'Document')

    el_fol = SubElement(el_doc, 'Folder')

    # Lock before scanning the directory, unlock on exit
    lockfile = os.path.join(os.path.dirname(args.outfile),
                            '.%s.lock' % os.path.basename(args.outfile))
    lockh = open(lockfile, 'w')
    try:
        lockf(lockh, LOCK_EX | LOCK_NB)
    except IOError:
        print('Could not create exclusive lock, assuming another process is running.')
        sys.exit(0)

    for filename in glob.glob(args.filepattern):
        with open(filename) as data_file:
            try:
                ydata = yaml.load(data_file, Loader=yaml.FullLoader)
            except yaml.ParserError as ex:
                print('Error parsing yaml in %s' % filename)
                print(ex)
                continue

            if 'name' not in ydata.keys() or 'email' not in ydata.keys():
                print('No name or email found in %s' % filename)
                continue

            if 'locations' not in ydata.keys() or len(ydata['locations']) < 1:
                print('No locations found in %s' % filename)
                continue

            for place in ydata['locations'].keys():
                location = ydata['locations'][place]
                # Find coords and make sure they are sane
                if 'latlong' not in location.keys():
                    print('No coordinates for location "%s" in file %s' % (place, filename))
                    continue

                latlong = location['latlong'].split(',')

                try:
                    if len(latlong) < 2:
                        raise ValueError('Missing comma')

                    # Bizarrely, KML wants longitude first
                    roundlevel = 6
                    if args.privround:
                        roundlevel = 2

                    lat = round(float(latlong[0].strip()), roundlevel)
                    lon = round(float(latlong[1].strip()), roundlevel)
                    coords = '%.6f,%.6f' % (lon, lat)

                except ValueError:
                    print('Invalid coordinates for location "%s" in file %s' % (place, filename))
                    continue

                el_placemark = SubElement(el_fol, 'Placemark')
                el_name = SubElement(el_placemark, 'name')
                el_name.text = ydata['name']

                el_point = SubElement(el_placemark, 'Point')
                el_coordinates = SubElement(el_point, 'coordinates')
                el_coordinates.text = coords

                email = ydata['email'].strip().lower()
                if hasattr(email, 'encode'):
                    email = email.encode('ascii')
                libavhash = hashlib.md5(email).hexdigest()

                desc = '''
                    <div class="devpop">
                    <img class="devimg" src="https://seccdn.libravatar.org/avatar/%s?s=64&amp;d=retro"/>
                    <p><b>Contact:</b>&nbsp;<a href="mailto:%s">%s</a>
                    ''' % (libavhash, ydata['email'], ydata['email'])

                if 'key' in ydata.keys():
                    desc += '''<br/>
                    <b>Key stats:</b>&nbsp;<a href="http://pgp.cs.uu.nl/stats/%s.html">%s</a>
                    ''' % (ydata['key'], ydata['key'])
                desc += '</p><p class="devclear">'

                if 'description' in location.keys():
                    desc += location['description'].strip()

                desc += '</p></div>'

                el_description = SubElement(el_placemark, 'description')
                el_description.text = CDATA(desc)

    kml_data = tostring(el_kml, pretty_print=True, encoding='utf-8')

    if args.dryrun:
        print(kml_data)
        sys.exit(0)

    with open(args.outfile, 'wb') as tfile:
        tfile.write(kml_data)
