#!/usr/bin/python
##############################################################################
# Copyright (c) Members of the EGEE Collaboration. 2010.
# See http://www.eu-egee.org/partners/ for details on the copyright
# holders.
#
# Licensed 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.
##############################################################################
#
# NAME :        glite-info-create
#
# DESCRIPTION : This script helps you create LDIF files.
#
# AUTHORS :     David.Horat@cern.ch
#               Laurence.Field@cern.ch
#
# WEB:          http://cern.ch/gridinfo
#
##############################################################################
import os
import sys
import getopt
import logging

# Funtion to print out the usage
def usage():
    sys.stderr.write('Usage: %s -m <module> [OPTIONS] \n' % (sys.argv[0]))
    sys.stderr.write('''
  glite-info-create.sh -m <module> [-i <ifaces>] [-t <templates>] [-c <configs>]
                       [-p <path>] [-o <outpath>] [-d debug]
       
Parameters:
  -m <module>    The module you are using. E.g.: site
  -i <ifaces>    The interface you want to use. E.g.: glue, wlcg (default)
  -t <templates> The template you want to use. E.g.: glue1, glue2 (all default)
  -c <config>    The config file location if outside from the module directory
  -p <path>      The path for the module directory. Default: /etc/glite-info-static
  -d <debug>     Debug level: 0:ERROR, 1:WARNING, 2:INFO, 3:DEBUG. Default: 0

Examples:
  glite-info-create.sh -m site
  glite-info-create.sh -m site -i 'glue wlcg' -t glue2 -c /etc/site.cfg

Web site: http://cern.ch/gridinfo
''')

def parse_options():
    global config

    config = {}
    config['debug'] = 0
    config['ifaces'] = []
    config['templates'] = []
    config['path'] = '/etc/glite-info-static'
    try:
        opts, args = getopt.getopt(sys.argv[1:], "i:t:c:m:p:d:h",
          ["ifaces", "templates", "config", "module", "path", "debug", "help"])
    except getopt.GetoptError:
        sys.stderr.write("Error: Invalid option specified.\n")
        usage()
        sys.exit(2)
    for o, a in opts:
        if o in ("-i", "--ifaces"):
            config['ifaces'].append(a)
        if o in ("-t", "--templates"):
            config['templates'].append(a)
        if o in ("-c", "--configs"):
            config['config'] = a
        if o in ("-m", "--module"):
            config['module'] = a
        if o in ("-p", "--path"):
            config['path'] = a
        if o in ("-d", "--debug"):
            config['debug'] = a
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)

    try:
        config['debug'] = int(config['debug'])
    except:
        sys.stderr.write("Error: Invalid logging level.\n")
        usage()
        sys.exit(1)
    if (config['debug'] > 3 or config['debug'] < 0 ):
        sys.stderr.write("Error: Invalid logging level.\n")
        usage()
        sys.exit(1)

    if ( not config.has_key('module') ):
        sys.stderr.write("Error: Mandatory option -m <module> must be specified.\n")
        usage()
        sys.exit(1)

    if ( not config.has_key('config') ):
        sys.stderr.write("Error: Mandatory option -c <config> must be specified.\n")
        usage()
        sys.exit(1)

    if ( len(config['ifaces']) == 0):
        config['ifaces'] = ['glue','wlcg']
    
    if ( len(config['templates']) == 0):
        config['templates'] = ['glue1','glue2']

    return


def main():
    global config, log

    module = config['module']

    # Get key-values from the configuration file.
    config_file="%s/%s/%s" %(config['path'], module, config['config'])   
    if ( not os.path.exists(config_file) ):
        log.error("Config file %s does not exist."%(config_file))
        sys.exit(1)
    parameters = {}
    for line in open(config_file).readlines():
        index = line.find('=')
        if ( index > 0 ):
            key = line[:index].strip()
            value = line[index+1:].strip()
            if ( not parameters.has_key(key) ):
                parameters[key] = []
            parameters[key].append(value)
            
    # Get the mandatory and optional attributes from the interface file.
    for interface in config['ifaces']:
        interface_file="%s/%s/%s.%s.ifc" %(config['path'], module, module, interface)   
        if ( not os.path.exists(interface_file) ):
            log.error("Interface file %s does not exist."%(interface_file))
            sys.exit(1)
        interface_parameters = {}
        for line in open(interface_file).readlines():
            index = line.find('=')
            if ( index > 0 ):
                key = line[:index].strip()
                value = line[index+1:].strip()
                if ( not value == ''):
                    values = value.split(" ")
                else:
                    values = []
                if ( not interface_parameters.has_key(key) ):
                    interface_parameters[key] = []
                interface_parameters[key].extend(values)

    # Check the configuration file for the mandatory and optional attributes.
    mandatory_attributes = []
    mandatory_attributes.extend(interface_parameters['MANDATORY_SINGLEVALUED_VARS'])
    mandatory_attributes.extend(interface_parameters['MANDATORY_MULTIVALUED_VARS'])
    for key in mandatory_attributes:
        if ( parameters.has_key(key)):
            for value in parameters[key]:
                if ( value == '' ):
                    log.error('Mandatory atribute %s does not have a value.' %(key))
                    sys.exit(1)
        else:
            log.error('Mandatory attribute %s is not specified in the configuration file' % (key))
            sys.exit(1)

    optional_attributes = []
    optional_attributes.extend(interface_parameters['OPTIONAL_SINGLEVALUED_VARS'])

    optional_attributes.extend(interface_parameters['OPTIONAL_MULTIVALUED_VARS'])

    for key in optional_attributes:
        if ( parameters.has_key(key)):
            for value in parameters[key]:
                if ( value  == '' ):
                    log.error('Optional atribute %s does not have a value.' %(key))
                    sys.exit(1)

    # Check that single valued attributes are really single
    singlevalued_attributes = []
    singlevalued_attributes.extend(interface_parameters['MANDATORY_SINGLEVALUED_VARS'])
    singlevalued_attributes.extend(interface_parameters['OPTIONAL_SINGLEVALUED_VARS'])
    for key in singlevalued_attributes:
        if ( parameters.has_key(key)):
            if ( len(parameters[key]) > 1 ):
                log.error('Single valued atribute %s has more than one value.' %(key))
                sys.exit(1)

    ldif = ""

    # Get the default ldif from the template.
    for template in config['templates']:
        template_file = "%s/%s/%s.%s.tpl" %(config['path'], module, module, template) 
        if ( not os.path.exists(template_file) ):
            log.error("Template file %s does not exist."%(template_file))
            sys.exit(1)

        ldif = open(template_file).read()

    multivalued_attributes = []
    multivalued_attributes.extend(interface_parameters['MANDATORY_MULTIVALUED_VARS'])
    multivalued_attributes.extend(interface_parameters['OPTIONAL_MULTIVALUED_VARS'])

    # Do the substitution for single valued attributes
    for attribute in singlevalued_attributes:
        # If there is no value then delete the line, otherwise substitute it.
        if ( parameters.has_key(attribute) ):
            for value in parameters[attribute]:
                if ( not parameters[attribute] == ''):
                    ldif = ldif.replace('$'+attribute, value)
            else:
                ldif = ldif.replace('$'+attribute, '')
        else:
            ldif = ldif.replace('$'+attribute, '')

    # Do the substitution for multivalued attributes
    for attribute in multivalued_attributes:
        # If there is no value then delete the line, otherwise substitute it.
        if ( parameters.has_key(attribute) ):
            end = ldif.find('$'+attribute)
            start = ldif[:end].rfind('\n') + 1
            glue_attribute = ldif[start:end]
            chunk = ""
            for value in parameters[attribute]:
                if ( not parameters[attribute] == ''):
                    chunk += glue_attribute + value + '\n'
            ldif = ldif.replace(glue_attribute+'$'+attribute, chunk[:-1])
        else:
            ldif = ldif.replace('$'+attribute, '')

    print ldif


if __name__ == "__main__":
    global config, log
         
    parse_options()

    log = logging.getLogger('%s' %(sys.argv[0]))
    hdlr = logging.StreamHandler(sys.stderr)
    formatter = logging.Formatter('[%(levelname)s]: %(message)s')
    hdlr.setFormatter(formatter)
    log.addHandler(hdlr)
    log.setLevel(config['debug'])
    main()
