/*
 * 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.
 */

// Verify the OSGI-INF xml files generated by the bnd plugin based
// on our annotations

def INVALID_CONFIG = 'Configuration is invalid'

// Utility functions
def getXml(filename) {
    return new XmlSlurper().parse(new File(basedir, "target/classes/OSGI-INF/" + filename)) 
}

def assertTypedAttribute(xml, name, type, value) {
    assert(xml.property.find{ it.@name == name && it.@type == type && it.@value == value })
}

def assertProperty(xml, name, String [] expected) {
    def linesFromXml = xml.property.find{ it.@name == name }.toString().split('\n')
    expected.each {
        assert(linesFromXml.contains(it))
    }
    assert(linesFromXml.length == expected.length)
}

// The actual tests
{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.DeprecatedAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'org.apache.sling.api.SlingHttpServletRequest')
    assertProperty(xml, 'adapters', 'org.apache.sling.api.resource.Resource')
    assertTypedAttribute(xml, 'adapter.deprecated', 'Boolean', 'true')
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.IntegerAndShortToLongAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'java.lang.Integer', 'java.lang.Short')
    assertProperty(xml, 'adapters', 'java.lang.Long')
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.InvalidEmptyAdapterFactory.xml")
    assertTypedAttribute(xml, 'adapter.condition', 'String', INVALID_CONFIG)
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.InvalidNoAdaptablesAdapterFactory.xml")
    assertProperty(xml, 'adapters', 'java.lang.Void')
    assertTypedAttribute(xml, 'adapter.condition', 'String', INVALID_CONFIG)
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.InvalidNoAdaptersAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'java.lang.Void')
    assertTypedAttribute(xml, 'adapter.condition', 'String', INVALID_CONFIG)
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.LongToIntegerIfFitsAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'java.lang.Long')
    assertProperty(xml, 'adapters', 'java.lang.Integer')
    assertTypedAttribute(xml, 'adapter.condition', 'String', 'If the value is small enough to fit in an integer.')
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.ShortToIntegerAndLongAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'java.lang.Short')
    assertProperty(xml, 'adapters', 'java.lang.Long', 'java.lang.Integer')
}

{
    def xml = getXml("org.apache.sling.adapter.annotations.testing.adapters.TextLengthIfFitsAdapterFactory.xml")
    assertProperty(xml, 'adaptables', 'java.lang.CharSequence', 'java.lang.String')
    assertProperty(xml, 'adapters', 'java.lang.Short', 'java.lang.Integer', 'java.lang.Long', 'java.math.BigInteger')
    assertTypedAttribute(xml, 'adapter.condition', 'String', 'If the text length fits in the requested type.')
}