#!/usr/bin/env python
# -----------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# -----------------------------------------------------------------------

import os
import re
import sys
import time
import getopt

from ducc_util import DuccUtil                        # sets the sys.path so we can find stuff
from properties import Properties
from properties import Property

class DuccPropManager:
    def __init__(self):
        # simple bootstrap to establish DUCC_HOME and to set the python path so it can
        # find the common code in DUCC_HOME/admin
        # Infer DUCC_HOME from our location - no longer use a (possibly inaccurate) environment variable
        me = os.path.abspath(__file__)    
        ndx = me.rindex('/')
        ndx = me.rindex('/', 0, ndx)
        self.DUCC_HOME = me[:ndx]          # split from 0 to ndx

    def merge(self, file1, file2, file3):
        '''
            Merge "file1" and "file2" to produce a merged "file3".
        '''
        file1_props = Properties()
        file1_props.load(file1)

        file2_props = Properties()
        file2_props.load(file2)

        file3_props = Properties()

        # Check for a site specification override of the property renamed in 2.1.0
        oname = 'ducc.threads.limit'
        nname = 'ducc.job.max.pipelines.count'
        prop = file2_props.get_property(oname)
        if prop != None:
            prop.c.append('# RENAMED by merger ' + time.strftime('%c') + ' old name: ' + prop.k)
            prop.k = nname
            file2_props.put_property(prop)
            file2_props.delete(oname)

        # first pass, create merged props with stuff in base props file updated with delta
        for k in file1_props.get_keys():
            base = file1_props.get_property(k)
            upd = file2_props.get_property(k)
            if ( upd == None ):
                file3_props.put_property(base)
            else:
                upd.c.append('# OVERRIDE by merger ' + time.strftime('%c') + ' old value: ' + base.v)
                file3_props.put_property(upd)
                file2_props.delete(k)

        # everything left in delta is new stuff
        for k in file2_props.get_keys():
            upd = file2_props.get_property(k)
            upd.c.append('# INSERT by merger ' + time.strftime('%c'))
            file3_props.put_property(upd)

		# automagically fix // in path to java
        prop = file3_props.get_property('ducc.jvm')
        prop.v = prop.v.replace('//', '/')
        file3_props.put_property(prop)
		
        file3_props.write(file3)

    def delta(self, left, right, delta):
        '''
            Compare "left" to "right" to produce a "delta".
        '''

        left_props = Properties()
        left_props.load(left)

        right_props = Properties()
        right_props.load(right)

        delta_props = Properties()

        for k in left_props.get_keys():
            r = left_props.get_property(k)
            if ( r == None ):          
                continue                                # left only, 'master' no need to delta it

            l = left_props.get_property(k)
            r = right_props.get_property(k)
            if ( r != None and l.v != r.v ):
                delta_props.put_property(r)            # no match, save difference (right) in delta

            right_props.delete(k)                        # shrink left to see what's left over

        for k in right_props.get_keys():
            delta_props.put_property(right_props.get_property(k))
            
        delta_props.write(delta)

    def usage(self, *msg):
        if ( msg[0] != None ):
            print ''
            print ' '.join(msg)
            print ''

        print 'ducc_prop_manager has two functions:'
        print '    1. Merge a local properties file with a default file to produce a merged ducc.properties.'
        print '    2. Compare two properties files to create a local delta.'
        print ''
        print '    The merge and delta operations are inverse operations.'
        print ''
        print '    Comments and the structure of the default file are preserved whenever possible.'
        print ''
        print '    If the full path name to a file is not given, it is must reside within'
        print'        $DUCC_HOME/resources'
        print ''
        print "Usage:"
        print '   ducc_prop_manager --merge file1 --with file2 --to file3'
        print '   ducc_prop_manager --delta file1 --with file2 --to file3'
        print ''
        print 'Options'
        print '    -m, --merge file1'
        print '    -d, --delta file1'
        print '           This is the base properties file, usually the unmodified file provided with the'
        print '           DUCC distribution.'
        print ''
        print '           If --merge is specified, the output file (file3) is the merger of file1 and file2'
        print ''
        print '           If --delta is specified, the output file (file3) is the delta of file1 and file2'
        print ''
        print '    -w, --with file2'
        print '          This file is either merged or difference with file1 to produce the result in file3'
        print ''
        print '    -t, --to file3'
        print '          This is the result of the merge or delta operation'
        print ''
        print 'Examples:'
        print '    Update your ducc.properties from the default properties and your site.ducc.properties:'
        print '        ducc_props_manager --merge default.ducc.properties --with site.ducc.properties --to ducc.properties'
        print ''
        print '    Create a new site.ducc.properties by differencing the default properties and ducc.properties'
        print '        ducc_props_manager --delta default.ducc.properties --with ducc.properties --to site.ducc.properties'

        sys.exit(1);

    def main(self, argv):          
        action = None
        file1 = None
        file2 = None
        file3 = None
        try:
            opts, args = getopt.getopt(argv, 'm:w:t:h?', ['delta=', 'merge=', 'with=', 'to=', 'help'])
        except:
            self.usage('Invalid arguments', ' '.join(argv))
                  
        for ( o, a ) in opts:
            if o in ( '-m', '--merge' ): 
                action = 'merge'
                file1 = a
            elif o in ( '-d', '--delta' ):
                action = 'delta'
                file1 = a
            elif o in ( '-w', '--with' ):
                file2 = a
            elif o in ( '-t', '--to' ):
                file3 = a

            elif o in ('-h', '-?', '--help'):
                self.usage(None);

        if ( action == None or file1 == None or file2 == None or file3 == None ):
            self.usage("Insufficient arguemnts.  All arguments are required.")

        if ( not ( file1.startswith('/') or file1.startswith('.') ) ):
            file1 = '/'.join([self.DUCC_HOME, 'resources', file1])

        if ( not ( file2.startswith('/') or file2.startswith('.') ) ):
            file2 = '/'.join([self.DUCC_HOME, 'resources', file2])

        if ( not ( file3.startswith('/') or file3.startswith('.') ) ):
            file3 = '/'.join([self.DUCC_HOME, 'resources', file3])

        if ( action == 'merge' ):
            self.merge(file1, file2, file3)
        elif ( action == 'delta'):
            self.delta(file1, file2, file3)
        else:
            self.usage('Invalid action:', action, 'must be --delta or --merge')

if __name__ == "__main__":
    mgr = DuccPropManager()
    mgr.main(sys.argv[1:])
