#!/usr/bin/env python
import git
import json

repo = git.Repo()
vrt_filename = 'vulnerability-rating-taxonomy.json'
latest_vrt_json = json.loads(open(vrt_filename).read())['content']
deprecated_json = json.loads(open('deprecated-node-mapping.json').read())

def load_version(repo, version, filename):
    version_dict = repo.git.show('%s:%s' % (version, filename))
    return json.loads(version_dict)['content']

def dig_tree(version_json, id_list):
    if len(id_list) == 1:
        return [node for node in version_json if node.get('id') == id_list[0]][0]
    return dig_tree(
        [node for node in version_json if node.get('id') == id_list[0]][0]['children'],
        id_list[1:]
    )

def check_mapping(vrt_id):
    id_list = vrt_id.split('.')
    try:
        dig_tree(latest_vrt_json, id_list)
        return True
    except (KeyError, IndexError) as e:
        if len(id_list) == 1:
            return False
        else:
            return check_mapping('.'.join(id_list[0:-1]))


def validate_subtree(prefix, subtree):
    errors = []
    for node in subtree:
        vrt_id = '.'.join(filter(None, [prefix, node['id']]))
        new_prefix = vrt_id

        if vrt_id in deprecated_json:
            max_ver = sorted(deprecated_json[vrt_id].keys(), key=lambda s: map(int, s.split('.')))[-1]
            print 'Deprecated node %s mapped to %s' % (vrt_id, deprecated_json[vrt_id][max_ver])
            vrt_id = deprecated_json[vrt_id][max_ver]

        if vrt_id == 'other':
            continue
        elif check_mapping(vrt_id):
            if 'children' in node:
                errors.extend(validate_subtree(new_prefix, node['children']))
        else:
            errors.append(vrt_id)
    return errors



def main():
    '''
    Validates that all nodes from previous versions have a valid mapping in the current version
    '''
    errors = {}

    for tag in repo.tags:
        print '\n-- Validating %s Mapping --' % tag.name
        version_json = load_version(repo, tag.name, vrt_filename)
        version_errors = validate_subtree('', version_json)
        if version_errors:
            errors[tag.name] = version_errors
    return errors

if __name__ == '__main__':
    main()
