#!/usr/bin/python

# ****************************************
# +++  BioCASE 
# +++  CMF Transfer v1.0
#
# Transfer mappings from one CMF to another.
# Transfers only equal XPath mappings and
# reports mappings that could not be tranfered.
#
# ****************************************


# ***** include the biocase.lib directory in the python sys path for importing *****
import os, sys
execfile( os.path.abspath(os.path.join(os.path.dirname( __file__ ), os.path.pardir, 'lib', 'biocase', 'adjustpath.py' ) ) )

# other imports
from biocase.wrapper.cmf_base import CMFClass
from biocase.wrapper.static_functions import getAbsoluteCWDirectory
from biocase.wrapper.cmf_handler import CMFVersionHandler
from biocase.configuration import Cfg
from os.path import join, getsize


############################################################################################################
#
# FUNCTIONS
#
#===========================================================================================================

def transferCMFConfigs(origCMFObj, newCMFObj, clean=False):
	'''Transfers all configurations from the original CMF object to the new CMF object.
	If parameter clean is set to True it removes all existing configs in the new CMF object.
	It returns the new object together with a dictionary (key=concept) of lists of mapping objects.'''
	if clean:
		newCMFObj.removeMappings()
		newCMFObj.removeFilters()
	# get data to transfer
	mapDict      = origCMFObj.removeMappings()
	filterDict   = origCMFObj.removeFilters()
	rootAlias    = origCMFObj.tableTreeObj.rootTableAlias
	staticTables = origCMFObj.tableTreeObj.staticTables
	# add data to new CMF
	unmatchedMappingDict = newCMFObj.setMappings(mapDict)
	unmatchedFilterDict  = newCMFObj.setFilters(filterDict)
	newCMFObj.tableTreeObj.rootTableAlias = rootAlias
	newCMFObj.tableTreeObj.staticTables   = staticTables
	# return unmatched concepts
	return (unmatchedMappingDict, unmatchedFilterDict)
	
	
def getBackupFilename(fn):
	'''create new backup filename that does not exist already for a file.'''
	newfn = '%s.bak' %(fn)
	i = 1
	while os.path.isfile(newfn):
		newfn = '%s.bak%i' %(fn, i)
		i+=1
	return newfn


############################################################################################################
#
# MAIN
#
#===========================================================================================================

if __name__ ==  "__main__":

	print '''
 +++  BioCASE 
 +++  CMF Transfer v1.0

 Transfer mappings from one CMF to another.
 Transfers only equal XPath mappings and
 reports mappings that could not be tranfered.

'''	
	# read configs
	cfg = Cfg()

	# ASK FOR ORIGINAL CMF
	origCMFFilePath = 'orig1.xml'
	while not os.path.isfile(origCMFFilePath):
		origCMFFilePath = raw_input("Please enter the path to the original CMFile: ")
	originalCMFObj = CMFClass()
	originalCMFObj.loadCMFdata(origCMFFilePath, pickle=False)

	# ASK FOR NEW CMF
	newCMFFilePath = 'new1.xml'
	while not os.path.isfile(newCMFFilePath):
		newCMFFilePath = raw_input("Please enter the path to the new CMFile: ")
	newCMFObj = CMFClass()
	newCMFObj.loadCMFdata(newCMFFilePath, pickle=False)
	
	# START TRANSFER
	(lostMaps, lostFilters) = transferCMFConfigs(originalCMFObj, newCMFObj)
	
	# WRITE NEW CMFILE
	# store a copy of the original new CMF
	bakFile = getBackupFilename(newCMFFilePath)
	os.rename(newCMFFilePath, bakFile)
	# write new CMF
	newCMFObj.writeCMF(newCMFFilePath)
	
	# REPORT FAILURES
	if len(lostMaps) > 0 or len(lostFilters) > 0:
		if len(lostMaps) > 0:
			print "Your original CMF contained MAPPINGS for concepts that dont exist in the new one."
			print "They were not transferred:"
			for concept in lostMaps:
				print "  %s"%concept
		if len(lostFilters) > 0:
			print "Your original CMF contained FILTERS for concepts that dont exist in the new one."
			print "They were not transferred:"
			for concept in lostFilters:
				print "  %s"%concept
	else:
		print "All configurations were safely transferred into your new CMF!"
	print
	print "-"*40
	print "Your new CMF contains the transferred mappings now."
	print "A copy of your original 'new CMF' was created as '%s'" %(bakFile)
	