#!/usr/bin/env python
"""link-convert.py -- retag link ways and roundabouts in Lithuania

Level of the link/roundabout is the same as highest level of the road/link 
it is connected to.

"""
from lxml.etree import parse, tostring
from bz2 import BZ2File
import re
from StringIO import StringIO
from httplib import HTTPConnection



changeset_body = """\
<osm>
  <changeset>
    <tag k="created_by" v="osm-convert.py"/>
    <tag k="comment" v="Promoting magistraliniai to trunk, krasto to primary, rajoniniai to secondary by an automated script."/>
  </changeset>
</osm>
"""

classes = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary', 'unclassified', 'residential', 'not connected']
cllevel = dict(zip(classes, range(len(classes))))
for cl in classes:
    cllevel[cl+'_link'] = cllevel[cl]

links = dict()
linknodes = dict()
nodeinlinks = dict()
emptyset = set()

def main():

    #dump = parse(BZ2File("lithuania.osm.2010-02-14.bz2"))
    dump = parse(BZ2File("lithuania-0215.osm.bz2"))

    """ fill up data structure
    """
    for way in dump.xpath("//way[tag[@k='highway' and contains(@v,'_link')]]|//way[tag[@k='highway'] and tag[@k='junction' and @v='roundabout']]"):
	wayid = way.xpath("@id")[0]
	links[wayid] = dict({ 'currlevel': cllevel[way.xpath("tag[@k='highway']/@v")[0]],
		'newlevel': len(classes)-1,
		'wayid': wayid,
		'roundabout': len(way.xpath("tag[@k='junction']"))>0 })
	nodeset = set(way.xpath("nd/@ref"))
	linknodes[wayid] = nodeset
	for node in nodeset:
	    nl = nodeinlinks.get(node, set())
	    nl.add(wayid)
	    nodeinlinks[node] = nl

    for way in dump.xpath("//way[tag[@k='highway' and @v='motorway']]"):
	upgrade_links(way.xpath("nd/@ref"), cllevel['motorway'])

    for way in dump.xpath("//way[tag[@k='highway' and @v='trunk']]"):
	upgrade_links(way.xpath("nd/@ref"), cllevel['trunk'])

    for way in dump.xpath("//way[tag[@k='highway' and @v='primary']]"):
	upgrade_links(way.xpath("nd/@ref"), cllevel['primary'])

    for way in dump.xpath("//way[tag[@k='highway' and @v='secondary']]"):
	upgrade_links(way.xpath("nd/@ref"), cllevel['secondary'])

    for way in dump.xpath("//way[tag[@k='highway' and @v='tertiary']]"):
	upgrade_links(way.xpath("nd/@ref"), cllevel['tertiary'])

    for l in links:
	link = links[l]
	if link['currlevel'] != link['newlevel']:
	    print "To site: %s change from %s to %s%s" % (link['wayid'], classes[link['currlevel']], classes[link['newlevel']], " (roundabout)" if link['roundabout'] else "")

"""	upgrade_links -- recursively traverse connected links and 
	upgrade their level to one supplied in second argument.
	Level is degraded in any case.
"""
def upgrade_links(nodes, level):
    for node in nodes:
	for link in nodeinlinks.get(node, emptyset):
	    if links[link]['newlevel'] > level:
		#print "Link %s need updating from %d to %d" % (link, links[link]['newlevel'], level) 
		links[link]['newlevel'] = level
		upgrade_links(linknodes[links[link]['wayid']], level)


if __name__ == '__main__':
    main()
