#!/usr/bin/python

import os
import pdb
import sys
import json

sys.path.append('.')

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")

from django.db.models.fields.related import ForeignKey

# defaults
apps = ["core", "hpc", "cord", "requestrouter"]
output = "-json"

# syntax: dmdot [-json | -dot] [app_name]

# poor man's argument parser
for arg in sys.argv[1:]:
    if arg.startswith("-"):
        output = arg
    else:
        app = arg

model_classes = []
class_names = []
lower_class_names = {}
synonyms = {
	'user':'creator'
}

for app in apps:
	app = app + ".models"
	#models_module = imp.load_source(app, ".")
	models_module = __import__(app)
	for part in app.split(".")[1:]:
	    if hasattr(models_module, "PlCoreBase"):
		break
	    models_module = getattr(models_module,part)

	PlCoreBase = getattr(models_module,"PlCoreBase")

	for classname in dir(models_module):
		c = getattr(models_module, classname, None)
		if type(c)==type(PlCoreBase):
			model_classes.append(c)
			class_names.append(c.__name__)
			lower_class_names[c.__name__.lower()] = c
			try:
				synonym = synonyms[c.__name__.lower()]
				lower_class_names[synonym] = c
			except: 
				pass    
				

# django doesn't use the correct case in field.name.title() for objects that
# have CamelCased class names. So, compare everything in lower case.

if (output=='-dot'):
        print "digraph plstack {";
        for c in model_classes:
                fields = c._meta.fields

                for f in fields:
                        if type(f)==ForeignKey and f.name.lower().split('_') in lower_class_names:
                                linked_class = lower_class_names[f.name.lower()]
				if ('backref' in f.name):
                                	print '\t"%s"->"%s";'%(linked_class.__name__,c.__name__)
				else:
                                	print '\t"%s"->"%s";'%(c.__name__,linked_class.__name__)
        print "}\n";
elif (output=='-json'):
        d = {}
        for c in model_classes:
                fields = c._meta.fields
		
                for f in fields:
			field_type = f.name.lower().split('_')[0]
                        if type(f)==ForeignKey and field_type in lower_class_names:
                                linked_class = lower_class_names[field_type]
				if ('backref' in f.name.lower()):
					a = linked_class.__name__
					b = c.__name__
				else:
					b = linked_class.__name__
					a = c.__name__

                                try:
					if (b not in d[a]):
                                        	d[a].append(b)
                                except KeyError:
                                        d[c.__name__]=[linked_class.__name__]
        #d['ControllerNetwork'].append('SliceDeployments')
        print json.dumps(d,indent=4)
        
        
