#!/usr/bin/python

import re
import os
import glob
import sys

MALFORMED = "malformed"

vomses_path = "vomses"
vomsdir     = "vomsdir"

def usage():
    print "usage: %s [vomses vomsdir]" % os.path.basename(__file__)
    print "   or: %s --system" % os.path.basename(__file__)
    print
    print "Use --system for /etc/vomses and /etc/grid-security/vomsdir"
    sys.exit()

if len(sys.argv) == 3:
    vomses_path = sys.argv[1]
    vomsdir     = sys.argv[2]
elif len(sys.argv) == 2 and sys.argv[1] == '--system':
    vomses_path = "/etc/vomses"
    vomsdir     = "/etc/grid-security/vomsdir"
elif len(sys.argv) != 1:
    usage()

for path in (vomses_path, vomsdir):
    if not os.path.exists(path):
        print "%s does not exist..." % path
        usage()

class vomses_entry:
    def __init__(self,arr):
        self.alias, self.host, self.port, self.dn, self.vo = arr
        self.lsc = os.path.join(self.alias, self.host) + ".lsc"

class lsc_entry:
    def __init__(self,arr):
        self.dn, self.ca = arr

def get_vomses():
    vomses = []
    for line in open(vomses_path):
        m = re.search(
            r'^"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"\s*$',
            line
        )
        if m:
            vomses.append(vomses_entry(m.groups()))
    return vomses

def get_lsc(entry):
    path = os.path.join(vomsdir, entry.lsc)
    if os.path.exists(path):
        lsc_entries = []
        fh = open(path)
        try:
            for line in fh:
                # Read lines two at a time
                dn_line = line.rstrip()
                ca_line = fh.next().rstrip()
                lsc_entries.append(lsc_entry((dn_line, ca_line)))
            return lsc_entries
        except StopIteration:
            # odd number of lines
            return MALFORMED
    else:
        return None

vomses_entries = get_vomses()

missing_lsc_files      = []
missing_vomses_entries = []
dn_mismatches          = []
# We can get duplicates of malformed .lsc files
malformed_lsc_files    = set()

for entry in vomses_entries:
    lsc_entries = get_lsc(entry)
    if lsc_entries is None:
        missing_lsc_files += ["Missing lsc file: %s" % entry.lsc]
    elif lsc_entries is MALFORMED:
        malformed_lsc_files.add("Malformed lsc file (incomplete DN/CA pair): %s" % entry.lsc)
    else:
        lsc_dns = [lsc.dn for lsc in lsc_entries]
        if entry.dn not in lsc_dns:
            dn_mismatches += [
                "DNs don't match for %s:" % entry.lsc,
                "  vomses: %s" % entry.dn,
                "     lsc: %s" % "\n" \
                "          ".join(lsc_dns)
            ]

vomses_lsc_files = set(entry.lsc for entry in vomses_entries)

os.chdir(vomsdir)
for lsc_path in sorted(glob.glob("*/*.lsc")):
    if lsc_path not in vomses_lsc_files:
        missing_vomses_entries += ["No vomses entry for %s" % lsc_path]

for x in (missing_lsc_files, malformed_lsc_files, missing_vomses_entries, dn_mismatches):
    if x:
        for line in x:
            print line
        print

