/*
 * 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.felix.scrplugin.om;

import java.util.ArrayList;
import java.util.List;

import org.apache.felix.scrplugin.Constants;
import org.apache.felix.scrplugin.SCRDescriptorException;
import org.apache.felix.scrplugin.helper.IssueLog;
import org.apache.felix.scrplugin.tags.*;

/**
 * <code>Component</code>
 * is a described component.
 *
 */
public class Component extends AbstractObject {

    /** The name of the component. */
    protected String name;

    /** Is this component enabled? */
    protected Boolean enabled;

    /** Is this component immediately started. */
    protected Boolean immediate;

    /** The factory. */
    protected String factory;

    /** The implementation. */
    protected Implementation implementation;

    /** All properties. */
    protected List<Property> properties = new ArrayList<Property>();

    /** The corresponding service. */
    protected Service service;

    /** The references. */
    protected List<Reference> references = new ArrayList<Reference>();

    /** Is this an abstract description? */
    protected boolean isAbstract;

    /** Is this a descriptor to be ignored ? */
    protected boolean isDs;

    /** Configuration policy. (V1.1) */
    protected String configurationPolicy;

    /** Activation method. (V1.1) */
    protected String activate;

    /** Deactivation method. (V1.1) */
    protected String deactivate;

    /** Modified method. (V1.1) */
    protected String modified;

    /** The spec version. */
    protected int specVersion;

    /**
     * Default constructor.
     */
    public Component() {
        this(null);
    }

    /**
     * Constructor from java source.
     */
    public Component(JavaTag t) {
        super(t);
    }

    /**
     * Get the spec version.
     */
    public int getSpecVersion() {
        return this.specVersion;
    }

    /**
     * Set the spec version.
     */
    public void setSpecVersion(int value) {
        // only set a higher version, never "downgrade"
        if (this.specVersion < value) {
            this.specVersion = value;
        }
    }

    /**
     * Return the associated java class description
     */
    public JavaClassDescription getJavaClassDescription() {
        if ( this.tag != null ) {
            return this.tag.getJavaClassDescription();
        }
        return null;
    }

    /**
     * @return All properties of this component.
     */
    public List<Property> getProperties() {
        return this.properties;
    }

    public void setProperties(List<Property> properties) {
        this.properties = properties;
    }

    public void addProperty(Property property) {
        this.properties.add(property);
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFactory() {
        return this.factory;
    }

    public void setFactory(String factory) {
        this.factory = factory;
    }

    public Boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public Boolean isImmediate() {
        return this.immediate;
    }

    public void setImmediate(Boolean immediate) {
        this.immediate = immediate;
    }

    public Implementation getImplementation() {
        return this.implementation;
    }

    public void setImplementation(Implementation implementation) {
        this.implementation = implementation;
    }

    public Service getService() {
        return this.service;
    }

    public void setService(Service service) {
        this.service = service;
    }

    public List<Reference> getReferences() {
        return this.references;
    }

    public void setReferences(List<Reference> references) {
        this.references = references;
    }

    public void addReference(Reference ref) {
        this.references.add(ref);
    }

    public boolean isAbstract() {
        return this.isAbstract;
    }

    public void setAbstract(boolean isAbstract) {
        this.isAbstract = isAbstract;
    }

    public boolean isDs() {
        return isDs;
    }

    public void setDs(boolean isDs) {
        this.isDs = isDs;
    }

    /**
     * Get the name of the activate method (or null for default)
     */
    public String getActivate() {
        return this.activate;
    }

    /**
     * Set the name of the deactivate method (or null for default)
     */
    public void setDeactivate(final String value) {
        this.deactivate = value;
    }

    /**
     * Get the name of the deactivate method (or null for default)
     */
    public String getDeactivate() {
        return this.deactivate;
    }

    /**
     * Set the name of the activate method (or null for default)
     */
    public void setActivate(final String value) {
        this.activate = value;
    }

    /**
     * Set the name of the modified method (or null for default)
     */
    public void setModified(final String value) {
        this.modified = value;
    }

    /**
     * Get the name of the modified method (or null for default)
     */
    public String getModified() {
        return this.modified;
    }

    /**
     * Validate the component description.
     * If errors occur a message is added to the issues list,
     * warnings can be added to the warnings list.
     */
    public void validate(final int specVersion, final IssueLog iLog)
    throws SCRDescriptorException {
        final int currentIssueCount = iLog.getNumberOfErrors();

        // nothing to check if this is ignored
        if (!isDs()) {
            return;
        }

        final JavaClassDescription javaClass = this.tag.getJavaClassDescription();
        if (javaClass == null) {
            this.logError( iLog, "Tag not declared in a Java Class" );
        } else {

            // if the service is abstract, we do not validate everything
            if ( !this.isAbstract ) {
                // ensure non-abstract, public class
                if (!javaClass.isPublic()) {
                    this.logError( iLog, "Class must be public: " + javaClass.getName() );
                }
                if (javaClass.isAbstract() || javaClass.isInterface()) {
                    this.logError( iLog, "Class must be concrete class (not abstract or interface) : " + javaClass.getName() );
                }

                // no errors so far, let's continue
                if ( iLog.getNumberOfErrors() == currentIssueCount ) {
                    final String activateName = this.activate == null ? "activate" : this.activate;
                    final String deactivateName = this.deactivate == null ? "deactivate" : this.deactivate;

                    // check activate and deactivate methods
                    this.checkLifecycleMethod(specVersion, javaClass, activateName, true, iLog);
                    this.checkLifecycleMethod(specVersion, javaClass, deactivateName, false, iLog);

                    if ( this.modified != null && specVersion >= Constants.VERSION_1_1 ) {
                        this.checkLifecycleMethod(specVersion, javaClass, this.modified, true, iLog);
                    }
                    // ensure public default constructor
                    boolean constructorFound = true;
                    JavaMethod[] methods = javaClass.getMethods();
                    for (int i = 0; methods != null && i < methods.length; i++) {
                        if (methods[i].isConstructor()) {
                            // if public default, succeed
                            if (methods[i].isPublic()
                                && (methods[i].getParameters() == null || methods[i].getParameters().length == 0)) {
                                constructorFound = true;
                                break;
                            }

                            // non-public/non-default constructor found, must have explicit
                            constructorFound = false;
                        }
                    }
                    if (!constructorFound) {
                        this.logError( iLog, "Class must have public default constructor: " + javaClass.getName() );
                    }

                    // verify properties
                    for(final Property prop : this.getProperties()) {
                        prop.validate(specVersion, iLog);
                    }

                    // verify service
                    boolean isServiceFactory = false;
                    if (this.getService() != null) {
                        if ( this.getService().getInterfaces().size() == 0 ) {
                            this.logError( iLog, "Service interface information is missing!" );
                        }
                        this.getService().validate(specVersion, iLog);
                        isServiceFactory = this.getService().isServicefactory();
                    }

                    // serviceFactory must not be true for immediate of component factory
                    if (isServiceFactory && this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
                        this.logError( iLog, "Component must not be a ServiceFactory, if immediate and/or component factory: " + javaClass.getName() );
                    }

                    // immediate must not be true for component factory
                    if (this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
                        this.logError( iLog, "Component must not be immediate if component factory: " + javaClass.getName() );
                    }
                }
            }
            if ( iLog.getNumberOfErrors() == currentIssueCount ) {
                // verify references
                for(final Reference ref : this.getReferences()) {
                    ref.validate(specVersion, this.isAbstract, iLog);
                }
            }
        }
        // check additional stuff if version is 1.1
        if ( specVersion >= Constants.VERSION_1_1 ) {
            final String cp = this.getConfigurationPolicy();
            if ( cp != null
                 && !Constants.COMPONENT_CONFIG_POLICY_IGNORE.equals(cp)
                 && !Constants.COMPONENT_CONFIG_POLICY_REQUIRE.equals(cp)
                 && !Constants.COMPONENT_CONFIG_POLICY_OPTIONAL.equals(cp) ) {
                this.logError( iLog, "Component has an unknown value for configuration policy: " + cp );
            }

        }
    }

    private static final String TYPE_COMPONENT_CONTEXT = "org.osgi.service.component.ComponentContext";
    private static final String TYPE_BUNDLE_CONTEXT = "org.osgi.framework.BundleContext";
    private static final String TYPE_MAP = "java.util.Map";
    private static final String TYPE_INT = "int";
    private static final String TYPE_INTEGER = "java.lang.Integer";

    /**
     * Check for existence of lifecycle methods.
     * @param specVersion The spec version
     * @param javaClass The java class to inspect.
     * @param methodName The method name.
     * @param warnings The list of warnings used to add new warnings.
     */
    protected void checkLifecycleMethod(final int specVersion,
                                        final JavaClassDescription javaClass,
                                        final String methodName,
                                        final boolean isActivate,
                                        final IssueLog iLog)
    throws SCRDescriptorException {
        // first candidate is (de)activate(ComponentContext)
        JavaMethod method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_COMPONENT_CONTEXT});
        if ( method == null ) {
            if ( specVersion >= Constants.VERSION_1_1) {
                // second candidate is (de)activate(BundleContext)
                method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_BUNDLE_CONTEXT});
                if ( method == null ) {
                    // third candidate is (de)activate(Map)
                    method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_MAP});

                    if ( method == null ) {
                        // if this is a deactivate method, we have two additional possibilities
                        // a method with parameter of type int and one of type Integer
                        if ( !isActivate ) {
                            method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_INT});
                            if ( method == null ) {
                                method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_INTEGER});
                            }
                        }

                        // fourth candidate is (de)activate with two or three arguments (type must be BundleContext, ComponentCtx and Map)
                        // as we have to iterate now and the fifth candidate is zero arguments
                        // we already store this option
                        JavaMethod zeroArgMethod = null;
                        JavaMethod found = method;
                        final JavaMethod[] methods = javaClass.getMethods();
                        int i = 0;
                        while ( i < methods.length ) {
                            if ( methodName.equals(methods[i].getName()) ) {

                                if ( methods[i].getParameters().length == 0 ) {
                                    zeroArgMethod = methods[i];
                                } else if ( methods[i].getParameters().length >= 2 ) {
                                    boolean valid = true;
                                    for(int m=0; m<methods[i].getParameters().length; m++) {
                                        final String type = methods[i].getParameters()[m].getType();
                                        if ( !type.equals(TYPE_BUNDLE_CONTEXT)
                                              && !type.equals(TYPE_COMPONENT_CONTEXT)
                                              && !type.equals(TYPE_MAP) ) {
                                            // if this is deactivate, int and integer are possible as well
                                            if ( isActivate || (!type.equals(TYPE_INT) && !type.equals(TYPE_INTEGER)) ) {
                                                valid = false;
                                            }
                                        }
                                    }
                                    if ( valid ) {
                                        if ( found == null ) {
                                            found = methods[i];
                                        } else {
                                            // print warning
                                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName()
                                                + " occurs several times with different matching signature." );
                                        }
                                    }
                                }
                            }
                            i++;
                        }
                        if ( found != null ) {
                            method = found;
                        } else {
                            method = zeroArgMethod;
                        }
                    }
                }
            }
            // if no method is found, we check for any method with that name to print some warnings!
            if ( method == null ) {
                final JavaMethod[] methods = javaClass.getMethods();
                for(int i=0; i<methods.length; i++) {
                    if ( methodName.equals(methods[i].getName()) ) {
                        if ( methods[i].getParameters().length != 1 ) {
                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName()
                                + " has wrong number of arguments" );
                        } else {
                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName() + " has wrong argument "
                                + methods[i].getParameters()[0].getType() );
                        }
                    }
                }
            }
        }
        // method must be protected for version 1.0
        if ( method != null && specVersion == Constants.VERSION_1_0) {
            // check protected
            if (method.isPublic()) {
                this.logWarn( iLog, "Lifecycle method " + method.getName() + " should be declared protected" );
            } else if (!method.isProtected()) {
                this.logWarn( iLog, "Lifecycle method " + method.getName()
                    + " has wrong qualifier, public or protected required" );
            }
        }
    }

    /**
     * Return the configuration policy.
     */
    public String getConfigurationPolicy() {
        return this.configurationPolicy;
    }

    /**
     * Set the configuration policy.
     */
    public void setConfigurationPolicy(final String value) {
        this.configurationPolicy = value;
    }

    @Override
    public String toString() {
        return "Component " + this.name + " (" +
          "enabled=" + (enabled==null?"<notset>":enabled) +
          ", immediate=" + (immediate == null?"<notset>":immediate) +
          ", abstract=" + isAbstract +
          ", isDS=" + isDs +
          (factory != null ? ", factory="+factory:"")+
          (configurationPolicy != null ? ", configurationPolicy=" + configurationPolicy : "") +
          (activate != null ? ", activate=" + activate : "") +
          (deactivate != null ? ", deactivate=" + deactivate : "") +
          (modified != null ? ", modified=" + modified : "") +
          ", specVersion=" + specVersion +
          ", implementation=" + implementation +
          ", service=" + service +
          ", properties=" + properties +
          ", references=" + references +
          ")";
    }
}