#!/usr/bin/python

from __future__ import print_function
from sys import *
import os,re
from string import *

srcRoot='./'

from os.path import sep
import shutil

def getModule(dir):
	m=re.match('^.*?'+sep+'((extra|core)|((gui|lib|pkg)'+sep+'.*?))(|'+sep+'.*)$',dir)
	assert(m)
	return m.group(1).replace(sep,'-')

def walkSourceFiles():
	ret=[]
	for root, dirs, files in os.walk(srcRoot,topdown=True):
		for d in ('.svn','QGLViewer','triangulation','sqlite3x','miniWm3','py'):
			try: dirs.remove(d)
			except ValueError: pass
		for f in files:
			if f in ('stdafx.cpp',): continue
			if f.split('.')[-1] in ('cpp','cc','C'):
				ret+=((root,f),)
	return ret

sources=walkSourceFiles()
plugins=set()
for dir,f in sources:
	for l in open(dir+sep+f):
		if 'YADE_PLUGIN' in l and getModule(dir) not in ('core',): plugins.add(f.split('.')[0])

maxIncludeLevel=4
def grepCpp(path,f,level=0):
	fullF=path+sep+f; baseName=f.split('.')[0]
	linkDeps,featureDeps=set(),set()
	if level==maxIncludeLevel: return set(),set()
	#print path,f
	for l in open(fullF):
		m=re.match('^#include<([^/]*)/(.*)>.*$',l)
		if m:
			incMod=m.group(1); incHead=m.group(2); baseName=incHead.split('.')[0]; assert(len(incHead.split('.'))==2)
			if incMod=='core': continue
			#if baseName not in plugins: print f,incHead
			linkDeps.add(incHead.split('.')[0])
			continue
		m=re.match('^#include\s*"([^/]*)".*$',l)
		if m:
			inc=m.group(1); incBaseName=m.group(1).split('.')[0]
			if not os.path.exists(path+sep+m.group(1)):
				print("WARNING: file %s included from %s doesn't exist"%(m.group(1),fullF))
				pass
			else:
				if m.group(1).split('.')[0] not in plugins or incBaseName==baseName:
					linkDeps.update(grepCpp(path,m.group(1),level=level+1)[0])
			continue
		m=re.match('^YADE_REQUIRE_FEATURE\((.*)\).*',l)
		if m:
			featureDeps.add(m.group(1))
	return linkDeps,featureDeps
pluginLinks,pluginFeats,pluginSrcs={},{},{}
for dir,f in sources:
	if getModule(dir) in ('core',): continue
	if not getModule(dir).startswith('pkg'): continue
	link,feats=grepCpp(dir,f)
	plugin='.'.join(f.split('.')[:-1])
	pluginLinks[plugin],pluginFeats[plugin],pluginSrcs[plugin]=link,feats,dir+'/'+f
import shelve
cache=shelve.open('linkdeps.cache')
cache['pluginLinks'],cache['pluginFeats'],cache['pluginSrcs']=pluginLinks,pluginFeats,pluginSrcs
pluginLinks,pluginFeats,pluginSrcs=cache['pluginLinks'],cache['pluginFeats'],cache['pluginSrcs']
pluginObjs={}
for p in list(pluginLinks.keys()): pluginObjs[p]='packages'
cache.close()

def getPluginLibs(plugin):
	libs=set()
	myObj=pluginObjs[plugin]
	for lib in pluginLinks[plugin]:
		if pluginObjs[plugin]==myObj: continue
		try:
			libs.add(pluginObjs[lib])
		except KeyError:
			print('WARNING: plugin %s, missing lib %s'%(plugin,lib))
	return libs
allLibs=set();
for p in list(pluginSrcs.keys()): allLibs.update(getPluginLibs(p))
print("\tenv.SharedLibrary('packages',Split('"+' '.join(list(pluginSrcs.values()))+"'),LIBS=env['LIBS']+Split('"+' '.join(allLibs)+"'),CXXFLAGS=env['CXXFLAGS']+['--combine'])")
#print plugin,' '.join(feats)
#print f ,' '.join(feats)

