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

        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:])
