#!/usr/bin/env python
#FIXME Add license

##### Templates for features.xml
FEATURES_HEADER = '''\
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
          name="%(feature_repo_name)s">
'''
FEATURE_HEADER= '''\
    <feature name="%(feature_name)s" version="%(version)s"
             description="%(title)s">
'''
EXISTING_FEATURE = '        <feature>%s</feature>\n'
BUNDLE = '        <bundle>%s</bundle>\n'
FEATURE_FOOTER = '    </feature>\n'
FEATURES_FOOTER = '</features>'

##### Templates for app.xml
APP_HEADER = '''\
<?xml version="1.0" encoding="UTF-8"?>
<app name="%(app_name)s" origin="%(origin)s" version="%(version)s"
        title="%(title)s" category="%(category)s" url="%(url)s"
        featuresRepo="%(feature_repo_name)s"
        features="%(feature_name)s" apps="%(apps)s">
    <description>%(description)s</description>
'''
ARTIFACT = '    <artifact>%s</artifact>\n'
SECURITY = '''\
    <security>
%s
    </security>\n'''
APP_FOOTER = '</app>'

NON_OSGI_TAG = 'NON-OSGI'

def mvnUrl(bundle):
    #mvn-uri := 'mvn:' [ repository-url '!' ] group-id '/' artifact-id [ '/' [version] [ '/' [type] [ '/' classifier ] ] ] ]
    parts = bundle.split(':')
    prefix = 'mvn:'
    suffix = ''
    if len(parts) > 3:
        parts.insert(2, parts.pop()) # move version to the 3rd position
    if len(parts) >= 5:
        # check classifier for special non-OSGi tag
        i = parts[4].find(NON_OSGI_TAG)
        if i == 0:
            prefix = 'wrap:' + prefix
            suffix = '$Bundle-SymbolicName=%s.%s&amp;Bundle-Version=%s' % tuple(parts[0:3])
            if len(parts[4]) == len(NON_OSGI_TAG):
                parts.pop() # pop off empty classifier
                if parts[3].lower() == 'jar':
                    parts.pop() # pop off default extension: jar
            else:
                parts[4] = parts[4][len(NON_OSGI_TAG):]
    return prefix + '/'.join(parts) + suffix

def generateFeatureFile(feature_repo_name,
                        features = [],
                        **kwargs):
    values = {
        'feature_repo_name' : '-'.join(feature_repo_name.split(':')[1:3]),
    }

    output = FEATURES_HEADER % values

    for feature in features:
        output += feature

    output += FEATURES_FOOTER
    return output

def generateFeature(feature_name,
                    version,
                    title,
                    features = [],
                    bundles = [],
                    **kwargs):
    values = {
        'feature_name' : feature_name,
        'version' : version,
        'title' : title,
    }

    output = FEATURE_HEADER % values

    if features:
        for feature in features:
            output += EXISTING_FEATURE % feature

    if bundles:
        for bundle in bundles:
            output += BUNDLE % mvnUrl(bundle)

    output += FEATURE_FOOTER
    return output


def generateAppFile(app_name,
                    origin,
                    version,
                    title,
                    category,
                    url,
                    feature_repo_name,
                    feature_name,
                    description = None,
                    apps = [],
                    artifacts = [],
                    security= None,
                    **kwargs):
    values = {
        'app_name' : app_name,
        'origin' : origin,
        'version' : version,
        'title' : title,
        'category' : category,
        'url' : url,
        'feature_repo_name' : mvnUrl(feature_repo_name) + '/xml/features',
        'feature_name' : feature_name,
    }

    values['description'] = description if description else title
    values['apps'] = ','.join(apps) if apps else ''

    output = APP_HEADER % values

    for artifact in artifacts:
        output += ARTIFACT % mvnUrl(artifact)

    if security is not None:
        output += SECURITY % security

    output += APP_FOOTER
    return output

def write(name, msg):
    if name is not None:
        with open(name, "w") as file:
            file.write(msg)
    else:
        print msg

if __name__ == '__main__':
    import sys, optparse

    parser = optparse.OptionParser()
    parser.add_option("-O", "--output",   dest="output",       help="Output file")
    parser.add_option("-n", "--name",     dest="feature_coords", help="Feature MVN Coords")
    parser.add_option("-a", "--app",      dest="app_name",     help="App Name")
    parser.add_option("-o", "--origin",   dest="origin",       help="Origin")
    parser.add_option("-c", "--category", dest="category",     help="Category")
    parser.add_option("-u", "--url",      dest="url",          help="URL")
    parser.add_option("-v", "--version",  dest="version",      help="Version")
    parser.add_option("-t", "--title",    dest="title",        help="Title")
    parser.add_option("-r", "--repo",     dest="repo_name",    help="Repo Name")
    parser.add_option('-D', '--desc',     dest='desc',         help='Application description')
    parser.add_option('-s', '--security', dest='security',     help='Application security')

    parser.add_option('-b', '--bundle',
                      action="append", dest='included_bundles',
                      metavar="BUNDLE", help='Included Bundle (multiple allowed)')
    parser.add_option('-e', '--excluded-bundle',
                      action="append", dest='excluded_bundles',
                      metavar="BUNDLE", help='Excluded Bundle (multiple allowed)')
    parser.add_option('-f', '--feature',
                      action="append", dest='features',
                      metavar="FEATURE", help='Existing Feature (multiple allowed)')
    parser.add_option('-d', '--apps',
                      action="append", dest='apps',
                      metavar="FEATURE", help='Required App (multiple allowed)')

    parser.add_option("-A", "--write-app", dest="write_app", action="store_true")
    parser.add_option("-F", "--write-features", dest="write_features", action="store_true")
    parser.add_option("-E", "--write-feature", dest="write_feature", action="store_true")

    (options, args) = parser.parse_args()

    values = {}
    if options.feature_coords and options.version and options.title:
        parts = options.feature_coords.split(':')
        values['feature_name'] = parts[1] if len(parts) > 1 else parts[0]
        values['version'] = options.version
        values['title'] = options.title
    else:
        sys.stderr.write('ERROR: Feature Name, Version, and Title are required\n')
        sys.stderr.flush()
        sys.exit(1)

    if options.app_name and options.origin and options.category and options.url:
        values['app_name'] = options.app_name
        values['origin'] = options.origin
        values['category'] = options.category
        values['url'] = options.url
    elif options.write_app:
        sys.stderr.write('ERROR: Feature Name, Version, and Title are required\n')
        sys.stderr.flush()
        sys.exit(1)

    values['feature_repo_name'] = options.repo_name if options.repo_name \
                                    else options.feature_coords

    bundles = []
    if options.included_bundles:
        bundles += options.included_bundles
    if options.excluded_bundles:
        bundles += options.excluded_bundles
    if options.desc:
        values['description'] = options.desc

    feature = generateFeature(bundles=bundles,
                              features=options.features,
                              **values)

    if options.write_feature:
        write(options.output, feature)

    if options.write_features:
        write(options.output,
              generateFeatureFile(features=[ feature ], **values))

    if options.write_app:
        write(options.output,
              generateAppFile(artifacts=options.included_bundles,
                              apps=options.apps,
                              security=options.security,
                              **values))