#!/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

# try to make sure we're running from the right place
if (not os.path.exists("core")):
   if (os.path.exists("../core")):
      os.chdir("..")
   else:
      print >> sys.stderr, "Are you sure you're running dmdot from the root of an XOS installation"
      sys.exit(-1)

# defaults
apps = ["core", "services.hpc", "services.requestrouter", "services.onos"]
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:
        apps+= [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)
        
        
