#! /usr/bin/env python
# encoding: utf-8

import sys,re,os,optparse
import TaskGen,Task,Utils,preproc
from Logs import error,debug,warn
from TaskGen import taskgen,after,before,feature
REVISION="0.1.3"
fakelibtool_vardeps=['CXX','PREFIX']
def fakelibtool_build(task):
	env=task.env
	dest=open(task.outputs[0].abspath(env),'w')
	sname=task.inputs[0].name
	fu=dest.write
	fu("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by BKsys II code name WAF)\n")
	if env['vnum']:
		nums=env['vnum'].split('.')
		libname=task.inputs[0].name
		name3=libname+'.'+env['vnum']
		name2=libname+'.'+nums[0]
		name1=libname
		fu("dlname='%s'\n"%name2)
		strn=" ".join([name3,name2,name1])
		fu("library_names='%s'\n"%(strn))
	else:
		fu("dlname='%s'\n"%sname)
		fu("library_names='%s %s %s'\n"%(sname,sname,sname))
	fu("old_library=''\n")
	vars=' '.join(env['libtoolvars']+env['LINKFLAGS'])
	fu("dependency_libs='%s'\n"%vars)
	fu("current=0\n")
	fu("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
	fu("dlopen=''\ndlpreopen=''\n")
	fu("libdir='%s/lib'\n"%env['PREFIX'])
	dest.close()
	return 0
def read_la_file(path):
	sp=re.compile(r'^([^=]+)=\'(.*)\'$')
	dc={}
	file=open(path,"r")
	for line in file.readlines():
		try:
			_,left,right,_=sp.split(line.strip())
			dc[left]=right
		except ValueError:
			pass
	file.close()
	return dc
def apply_link_libtool(self):
	if self.type!='program':
		linktask=self.link_task
		self.latask=self.create_task('fakelibtool',linktask.outputs,linktask.outputs[0].change_ext('.la'))
	if self.bld.is_install:
		self.bld.install_files('${PREFIX}/lib',linktask.outputs[0],self.env)
def apply_libtool(self):
	self.env['vnum']=self.vnum
	paths=[]
	libs=[]
	libtool_files=[]
	libtool_vars=[]
	for l in self.env['LINKFLAGS']:
		if l[:2]=='-L':
			paths.append(l[2:])
		elif l[:2]=='-l':
			libs.append(l[2:])
	for l in libs:
		for p in paths:
			dict=read_la_file(p+'/lib'+l+'.la')
			linkflags2=dict.get('dependency_libs','')
			for v in linkflags2.split():
				if v.endswith('.la'):
					libtool_files.append(v)
					libtool_vars.append(v)
					continue
				self.env.append_unique('LINKFLAGS',v)
				break
	self.env['libtoolvars']=libtool_vars
	while libtool_files:
		file=libtool_files.pop()
		dict=read_la_file(file)
		for v in dict['dependency_libs'].split():
			if v[-3:]=='.la':
				libtool_files.append(v)
				continue
			self.env.append_unique('LINKFLAGS',v)
Task.task_type_from_func('fakelibtool',vars=fakelibtool_vardeps,func=fakelibtool_build,color='BLUE',after="cc_link cxx_link static_link")
class libtool_la_file:
	def __init__(self,la_filename):
		self.__la_filename=la_filename
		self.linkname=str(os.path.split(la_filename)[-1])[:-3]
		if self.linkname.startswith("lib"):
			self.linkname=self.linkname[3:]
		self.dlname=None
		self.library_names=None
		self.old_library=None
		self.dependency_libs=None
		self.current=None
		self.age=None
		self.revision=None
		self.installed=None
		self.shouldnotlink=None
		self.dlopen=None
		self.dlpreopen=None
		self.libdir='/usr/lib'
		if not self.__parse():
			raise"file %s not found!!"%(la_filename)
	def __parse(self):
		if not os.path.isfile(self.__la_filename):return 0
		la_file=open(self.__la_filename,'r')
		for line in la_file:
			ln=line.strip()
			if not ln:continue
			if ln[0]=='#':continue
			(key,value)=str(ln).split('=',1)
			key=key.strip()
			value=value.strip()
			if value=="no":value=False
			elif value=="yes":value=True
			else:
				try:value=int(value)
				except ValueError:value=value.strip("'")
			setattr(self,key,value)
		la_file.close()
		return 1
	def get_libs(self):
		libs=[]
		if self.dependency_libs:
			libs=str(self.dependency_libs).strip().split()
		if libs==None:
			libs=[]
		libs.insert(0,"-l%s"%self.linkname.strip())
		libs.insert(0,"-L%s"%self.libdir.strip())
		return libs
	def __str__(self):
		return'''\
dlname = "%(dlname)s"
library_names = "%(library_names)s"
old_library = "%(old_library)s"
dependency_libs = "%(dependency_libs)s"
version = %(current)s.%(age)s.%(revision)s
installed = "%(installed)s"
shouldnotlink = "%(shouldnotlink)s"
dlopen = "%(dlopen)s"
dlpreopen = "%(dlpreopen)s"
libdir = "%(libdir)s"'''%self.__dict__
class libtool_config:
	def __init__(self,la_filename):
		self.__libtool_la_file=libtool_la_file(la_filename)
		tmp=self.__libtool_la_file
		self.__version=[int(tmp.current),int(tmp.age),int(tmp.revision)]
		self.__sub_la_files=[]
		self.__sub_la_files.append(la_filename)
		self.__libs=None
	def __cmp__(self,other):
		if not other:
			return 1
		othervers=[int(s)for s in str(other).split(".")]
		selfvers=self.__version
		return cmp(selfvers,othervers)
	def __str__(self):
		return"\n".join([str(self.__libtool_la_file),' '.join(self.__libtool_la_file.get_libs()),'* New getlibs:',' '.join(self.get_libs())])
	def __get_la_libs(self,la_filename):
		return libtool_la_file(la_filename).get_libs()
	def get_libs(self):
		libs_list=list(self.__libtool_la_file.get_libs())
		libs_map={}
		while len(libs_list)>0:
			entry=libs_list.pop(0)
			if entry:
				if str(entry).endswith(".la"):
					if entry not in self.__sub_la_files:
						self.__sub_la_files.append(entry)
						libs_list.extend(self.__get_la_libs(entry))
				else:
					libs_map[entry]=1
		self.__libs=libs_map.keys()
		return self.__libs
	def get_libs_only_L(self):
		if not self.__libs:self.get_libs()
		libs=self.__libs
		libs=[s for s in libs if str(s).startswith('-L')]
		return libs
	def get_libs_only_l(self):
		if not self.__libs:self.get_libs()
		libs=self.__libs
		libs=[s for s in libs if str(s).startswith('-l')]
		return libs
	def get_libs_only_other(self):
		if not self.__libs:self.get_libs()
		libs=self.__libs
		libs=[s for s in libs if not(str(s).startswith('-L')or str(s).startswith('-l'))]
		return libs
def useCmdLine():
	usage='''Usage: %prog [options] PathToFile.la
example: %prog --atleast-version=2.0.0 /usr/lib/libIlmImf.la
nor: %prog --libs /usr/lib/libamarok.la'''
	parser=optparse.OptionParser(usage)
	a=parser.add_option
	a("--version",dest="versionNumber",action="store_true",default=False,help="output version of libtool-config")
	a("--debug",dest="debug",action="store_true",default=False,help="enable debug")
	a("--libs",dest="libs",action="store_true",default=False,help="output all linker flags")
	a("--libs-only-l",dest="libs_only_l",action="store_true",default=False,help="output -l flags")
	a("--libs-only-L",dest="libs_only_L",action="store_true",default=False,help="output -L flags")
	a("--libs-only-other",dest="libs_only_other",action="store_true",default=False,help="output other libs (e.g. -pthread)")
	a("--atleast-version",dest="atleast_version",default=None,help="return 0 if the module is at least version ATLEAST_VERSION")
	a("--exact-version",dest="exact_version",default=None,help="return 0 if the module is exactly version EXACT_VERSION")
	a("--max-version",dest="max_version",default=None,help="return 0 if the module is at no newer than version MAX_VERSION")
	(options,args)=parser.parse_args()
	if len(args)!=1 and not options.versionNumber:
		parser.error("incorrect number of arguments")
	if options.versionNumber:
		print("libtool-config version %s"%REVISION)
		return 0
	ltf=libtool_config(args[0])
	if options.debug:
		print(ltf)
	if options.atleast_version:
		if ltf>=options.atleast_version:return 0
		sys.exit(1)
	if options.exact_version:
		if ltf==options.exact_version:return 0
		sys.exit(1)
	if options.max_version:
		if ltf<=options.max_version:return 0
		sys.exit(1)
	def p(x):
		print(" ".join(x))
	if options.libs:p(ltf.get_libs())
	elif options.libs_only_l:p(ltf.get_libs_only_l())
	elif options.libs_only_L:p(ltf.get_libs_only_L())
	elif options.libs_only_other:p(ltf.get_libs_only_other())
	return 0
if __name__=='__main__':
	useCmdLine()

feature("libtool")(apply_link_libtool)
after('apply_link')(apply_link_libtool)
feature("libtool")(apply_libtool)
before('apply_core')(apply_libtool)
