/*
 *  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.
 */
package org.apache.ant.props;

import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.tools.ant.AntTypeDefinition;
import org.apache.tools.ant.ComponentHelper;
import org.apache.tools.ant.IntrospectionHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper;
import org.apache.tools.ant.TypeAdapter;
import org.apache.tools.ant.taskdefs.condition.Condition;

/**
 * Property evaluator that evaluates Ant conditions to a Boolean
 * instance matching the condition's outcome.
 *
 * <p>Default syntax is
 * <code>[!]<em>condition</em>(<em>attribute</em>=<em>value</em>)</code>,
 * for example <code>os(family=unix)</code> or <code>!os(family=unix)</code>.
 */
public class ConditionTypeEvaluator extends RegexBasedEvaluator {
    private static final Pattern COMMA = Pattern.compile(",");
    private static final Pattern EQ = Pattern.compile("=");

    private static final String ASSIGN_ATTR = "" //
            + "(?:.+?)" // reluctant one or more !=
            + "=" // equals
            + "(?:.+?)" // reluctant one or more chars
    ;
    private static final String PATTERN = "" //
            + "^" // beginning
            + "(!)?" // optional bang implying NOT, capturing group 1
            + "(.+?)" // reluctant one-or-more characters for condition name
            + "\\(" // LPAREN
            + "(" // capturing group 2, attribute assignments
            + "(?:" // open nc group ASSIGN_ATTR 1
            + ASSIGN_ATTR //
            + ")" // end nc group ASSIGN_ATTR 1
            + "(?:" // open nc group ASSIGN_ATTR 2..N
            + "," // delimiting comma
            + ASSIGN_ATTR //
            + ")*" // 0..N occurrences
            + ")" // end nc group ASSIGN_ATTR 2..N
            + "\\)" // RPAREN
            + "$" // EOF
    ;

    /**
     * Create a new ConditionTypeEvaluator instance.
     */
    public ConditionTypeEvaluator() {
        super(PATTERN);
    }

    /**
     * {@inheritDoc}
     */
    protected Object evaluate(String[] groups, PropertyHelper propertyHelper) {
        Project p = propertyHelper.getProject();
        boolean negate = false;
        if ("!".equals(groups[1])) {
            negate = true;
        }
        Condition cond = createCondition(p, groups[2]);
        if (cond != null) {
            if (groups[3].length() > 0) {
                Object realObject = TypeAdapter.class.isInstance(cond) ? ((TypeAdapter) cond)
                        .getProxy() : cond;
                if (realObject == null) {
                    throw new IllegalStateException(
                            "Found null proxy object for adapted condition " + cond.toString());
                }
                IntrospectionHelper ih = IntrospectionHelper.getHelper(realObject.getClass());
                String[] attributes = COMMA.split(groups[3]);
                for (int i = 0; i < attributes.length; i++) {
                    String[] keyValue = EQ.split(attributes[i]);
                    ih.setAttribute(p, realObject, keyValue[0].trim(), keyValue[1].trim());
                }
            }
            return Boolean.valueOf(cond.eval() ^ negate);
        }
        return null;
    }

    private Condition createCondition(Project project, String type) {
        Condition result = null;
        ComponentHelper componentHelper = ComponentHelper.getComponentHelper(project);
        Object o = componentHelper.createComponent(type);
        if (o instanceof Condition) {
            result = (Condition) o;
        } else {
            List restrictedDefinitions = componentHelper.getRestrictedDefinitions(type);
            for (Iterator iter = restrictedDefinitions.iterator(); iter.hasNext();) {
                AntTypeDefinition typeDefinition = (AntTypeDefinition) iter.next();
                Class exposedClass = typeDefinition.getExposedClass(project);
                if (exposedClass != null && Condition.class.isAssignableFrom(exposedClass)) {
                    try {
                        result = (Condition) typeDefinition.create(project);
                        break;
                    } catch (Exception e) {
                        project.log("Exception creating type " + typeDefinition, e,
                                Project.MSG_WARN);
                    }
                }
            }
        }
        return result;
    }

}
