/**
 * 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.activemq.ra;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Topic;
import javax.resource.ResourceException;
import javax.resource.spi.InvalidPropertyException;
import javax.resource.spi.ResourceAdapter;

import org.apache.activemq.RedeliveryPolicy;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.selector.SelectorParser;

/**
 * Configures the inbound JMS consumer specification using ActiveMQ
 * 
 * @org.apache.xbean.XBean element="activationSpec"
 *  $Date: 2007-08-11 17:29:21 -0400 (Sat, 11 Aug
 *          2007) $
 */
public class ActiveMQActivationSpec implements MessageActivationSpec, Serializable {

    /** Auto-acknowledge constant for <code>acknowledgeMode</code> property * */
    public static final String AUTO_ACKNOWLEDGE_MODE = "Auto-acknowledge";
    /** Dups-ok-acknowledge constant for <code>acknowledgeMode</code> property * */
    public static final String DUPS_OK_ACKNOWLEDGE_MODE = "Dups-ok-acknowledge";
    /** Durable constant for <code>subscriptionDurability</code> property * */
    public static final String DURABLE_SUBSCRIPTION = "Durable";
    /** NonDurable constant for <code>subscriptionDurability</code> property * */
    public static final String NON_DURABLE_SUBSCRIPTION = "NonDurable";
    public static final int INVALID_ACKNOWLEDGE_MODE = -1;

    private static final long serialVersionUID = -7153087544100459975L;

    private transient MessageResourceAdapter resourceAdapter;
    private String destinationType;
    private String messageSelector;
    private String destination;
    private String acknowledgeMode = AUTO_ACKNOWLEDGE_MODE;
    private String userName;
    private String password;
    private String clientId;
    private String subscriptionName;
    private String subscriptionDurability = NON_DURABLE_SUBSCRIPTION;
    private String noLocal = "false";
    private String useRAManagedTransaction = "false";
    private String maxSessions = "10";
    private String maxMessagesPerSessions = "10";
    private String enableBatch = "false";
    private String maxMessagesPerBatch = "10";
    private String trustStore;
    private String trustStorePassword;
    private String keyStore;
    private String keyStorePassword;
    private String keyStoreKeyPassword;
    private RedeliveryPolicy redeliveryPolicy;
    private boolean useJndi;

    /**
     * @see javax.resource.spi.ActivationSpec#validate()
     */
    public void validate() throws InvalidPropertyException {
        List<String> errorMessages = new ArrayList<String>();
        List<PropertyDescriptor> propsNotSet = new ArrayList<PropertyDescriptor>();
        try {
            if (!isValidDestination(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("destination", ActiveMQActivationSpec.class));
            }
            if (!isValidDestinationType(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("destinationType", ActiveMQActivationSpec.class));
            }
            if (!isValidAcknowledgeMode(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("acknowledgeMode", ActiveMQActivationSpec.class));
            }
            if (!isValidSubscriptionDurability(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("subscriptionDurability", ActiveMQActivationSpec.class));
            }
            if (!isValidClientId(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("clientId", ActiveMQActivationSpec.class));
            }
            if (!isValidSubscriptionName(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("subscriptionName", ActiveMQActivationSpec.class));
            }
            if (!isValidMaxMessagesPerSessions(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("maxMessagesPerSessions", ActiveMQActivationSpec.class));
            }
            if (!isValidMaxSessions(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("maxSessions", ActiveMQActivationSpec.class));
            }
            if (!isValidMessageSelector(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("messageSelector", ActiveMQActivationSpec.class));
            }
            if (!isValidNoLocal(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("noLocal", ActiveMQActivationSpec.class));
            }
            if (!isValidUseRAManagedTransaction(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("useRAManagedTransaction", ActiveMQActivationSpec.class));
            }
            if (!isValidEnableBatch(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("enableBatch", ActiveMQActivationSpec.class));
            }
            if (!isValidMaxMessagesPerBatch(errorMessages)) {
                propsNotSet.add(new PropertyDescriptor("maxMessagesPerBatch", ActiveMQActivationSpec.class));
            }

        } catch (IntrospectionException e) {
            e.printStackTrace();
        }

        if (propsNotSet.size() > 0) {
            StringBuffer b = new StringBuffer();
            b.append("Invalid settings:");
            for (Iterator<String> iter = errorMessages.iterator(); iter.hasNext();) {
                b.append(" ");
                b.append(iter.next());
            }
            InvalidPropertyException e = new InvalidPropertyException(b.toString());
            final PropertyDescriptor[] descriptors = propsNotSet.toArray(new PropertyDescriptor[propsNotSet.size()]);
            e.setInvalidPropertyDescriptors(descriptors);
            throw e;
        }
    }

    public boolean isValidUseRAManagedTransaction(List<String> errorMessages) {
        try {
            new Boolean(useRAManagedTransaction);
            return true;
        } catch (Throwable e) {
            //
        }
        errorMessages.add("useRAManagedTransaction must be set to: true or false.");
        return false;
    }

    public boolean isValidNoLocal(List<String> errorMessages) {
        try {
            new Boolean(noLocal);
            return true;
        } catch (Throwable e) {
            //
        }
        errorMessages.add("noLocal must be set to: true or false.");
        return false;
    }

    public boolean isValidMessageSelector(List<String> errorMessages) {
        try {
            if (!isEmpty(messageSelector)) {
                SelectorParser.parse(messageSelector);
            }
            return true;
        } catch (Throwable e) {
            errorMessages.add("messageSelector not set to valid message selector: " + e);
            return false;
        }
    }

    public boolean isValidMaxSessions(List<String> errorMessages) {
        try {
            if (Integer.parseInt(maxSessions) > 0) {
                return true;
            }
        } catch (NumberFormatException e) {
            //
        }
        errorMessages.add("maxSessions must be set to number > 0");
        return false;
    }

    public boolean isValidMaxMessagesPerSessions(List<String> errorMessages) {
        try {
            if (Integer.parseInt(maxMessagesPerSessions) > 0) {
                return true;
            }
        } catch (NumberFormatException e) {
            //
        }
        errorMessages.add("maxMessagesPerSessions must be set to number > 0");
        return false;
    }

    public boolean isValidMaxMessagesPerBatch(List<String> errorMessages) {
        try {
            if (Integer.parseInt(maxMessagesPerBatch) > 0) {
                return true;
            }
        } catch (NumberFormatException e) {
            //
        }
        errorMessages.add("maxMessagesPerBatch must be set to number > 0");
        return false;
    }

    public boolean isValidEnableBatch(List<String> errorMessages) {
        try {
            new Boolean(enableBatch);
            return true;
        } catch (Throwable e) {
            //
        }
        errorMessages.add("enableBatch must be set to: true or false");
        return false;
    }

    public ResourceAdapter getResourceAdapter() {
        return resourceAdapter;
    }

    /**
     * @see javax.resource.spi.ResourceAdapterAssociation#setResourceAdapter(javax.resource.spi.ResourceAdapter)
     */
    public void setResourceAdapter(ResourceAdapter resourceAdapter) throws ResourceException {
        // spec section 5.3.3
        if (this.resourceAdapter != null) {
            throw new ResourceException("ResourceAdapter already set");
        }
        if (!(resourceAdapter instanceof MessageResourceAdapter)) {
            throw new ResourceException("ResourceAdapter is not of type: " + MessageResourceAdapter.class.getName());
        }
        this.resourceAdapter = (MessageResourceAdapter)resourceAdapter;
    }

    // ///////////////////////////////////////////////////////////////////////
    //
    // Java Bean getters and setters for this ActivationSpec class.
    //
    // ///////////////////////////////////////////////////////////////////////
    public String getDestinationType() {
        if (!isEmpty(destinationType)) {
            return destinationType;
        }
        return null;
    }

    /**
     * @param destinationType The destinationType to set.
     */
    public void setDestinationType(String destinationType) {
        this.destinationType = destinationType;
    }

    public String getPassword() {
        if (!isEmpty(password)) {
            return password;
        }
        return null;
    }

    /**
     * 
     */
    public void setPassword(String password) {
        this.password = password;
    }

    public String getUserName() {
        if (!isEmpty(userName)) {
            return userName;
        }
        return null;
    }

    /**
     * 
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getMessageSelector() {
        if (!isEmpty(messageSelector)) {
            return messageSelector;
        }
        return null;
    }

    /**
     * @param messageSelector The messageSelector to set.
     */
    public void setMessageSelector(String messageSelector) {
        this.messageSelector = messageSelector;
    }

    public String getNoLocal() {
        return noLocal;
    }

    /**
     * @param noLocal The noLocal to set.
     */
    public void setNoLocal(String noLocal) {
        if (noLocal != null) {
            this.noLocal = noLocal;
        }
    }

    public String getAcknowledgeMode() {
        if (!isEmpty(acknowledgeMode)) {
            return acknowledgeMode;
        }
        return null;
    }

    /**
     * 
     */
    public void setAcknowledgeMode(String acknowledgeMode) {
        this.acknowledgeMode = acknowledgeMode;
    }

    public String getClientId() {
        if (!isEmpty(clientId)) {
            return clientId;
        }
        return null;
    }

    /**
     * 
     */
    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getDestination() {
        if (!isEmpty(destination)) {
            return destination;
        }
        return null;
    }

    /**
     * 
     */
    public void setDestination(String destination) {
        this.destination = destination;
    }

    public String getSubscriptionDurability() {
        if (!isEmpty(subscriptionDurability)) {
            return subscriptionDurability;
        }
        return null;
    }

    /**
     * 
     */
    public void setSubscriptionDurability(String subscriptionDurability) {
        this.subscriptionDurability = subscriptionDurability;
    }

    public String getSubscriptionName() {
        if (!isEmpty(subscriptionName)) {
            return subscriptionName;
        }
        return null;
    }

    /**
     * 
     */
    public void setSubscriptionName(String subscriptionName) {
        this.subscriptionName = subscriptionName;
    }

    public boolean isValidSubscriptionName(List<String> errorMessages) {
        if (!isDurableSubscription() ? true : subscriptionName != null && subscriptionName.trim().length() > 0) {
            return true;
        }
        errorMessages.add("subscriptionName must be set since durable subscription was requested.");
        return false;
    }

    public boolean isValidClientId(List<String> errorMessages) {
        if (!isDurableSubscription() ? true : clientId != null && clientId.trim().length() > 0) {
            return true;
        }
        errorMessages.add("clientId must be set since durable subscription was requested.");
        return false;
    }

    public boolean isDurableSubscription() {
        return DURABLE_SUBSCRIPTION.equals(subscriptionDurability);
    }

    public boolean isValidSubscriptionDurability(List<String> errorMessages) {
        // subscriptionDurability only applies to Topics
        if (DURABLE_SUBSCRIPTION.equals(subscriptionDurability) && getDestinationType() != null && !Topic.class.getName().equals(getDestinationType())) {
            errorMessages.add("subscriptionDurability cannot be set to: " + DURABLE_SUBSCRIPTION + " when destinationType is set to " + Queue.class.getName()
                              + " as it is only valid when destinationType is set to " + Topic.class.getName() + ".");
            return false;
        }
        if (NON_DURABLE_SUBSCRIPTION.equals(subscriptionDurability) || DURABLE_SUBSCRIPTION.equals(subscriptionDurability)) {
            return true;
        }
        errorMessages.add("subscriptionDurability must be set to: " + NON_DURABLE_SUBSCRIPTION + " or " + DURABLE_SUBSCRIPTION + ".");
        return false;
    }

    public boolean isValidAcknowledgeMode(List<String> errorMessages) {
        if (AUTO_ACKNOWLEDGE_MODE.equals(acknowledgeMode) || DUPS_OK_ACKNOWLEDGE_MODE.equals(acknowledgeMode)) {
            return true;
        }
        errorMessages.add("acknowledgeMode must be set to: " + AUTO_ACKNOWLEDGE_MODE + " or " + DUPS_OK_ACKNOWLEDGE_MODE + ".");
        return false;
    }

    public boolean isValidDestinationType(List<String> errorMessages) {
        if (Queue.class.getName().equals(destinationType) || Topic.class.getName().equals(destinationType)) {
            return true;
        }
        errorMessages.add("destinationType must be set to: " + Queue.class.getName() + " or " + Topic.class.getName() + ".");
        return false;
    }

    public boolean isValidDestination(List<String> errorMessages) {
        if (!(destination == null || destination.equals(""))) {
            return true;
        }
        errorMessages.add("destination is a required field and must be set to the destination name.");
        return false;
    }

    public boolean isEmpty(String value) {
        return value == null || "".equals(value.trim());
    }

    /**
     * 
     */
    @Override
    public String toString() {
        return "ActiveMQActivationSpec{" + "acknowledgeMode='" + acknowledgeMode + "'" + ", destinationType='" + destinationType + "'" + ", messageSelector='" + messageSelector + "'"
               + ", destination='" + destination + "'" + ", clientId='" + clientId + "'" + ", subscriptionName='" + subscriptionName + "'" + ", subscriptionDurability='" + subscriptionDurability
               + "'" + ", useJndi='"+ useJndi + "'" +"}";
    }

    public int getAcknowledgeModeForSession() {
        if (AUTO_ACKNOWLEDGE_MODE.equals(acknowledgeMode)) {
            return Session.AUTO_ACKNOWLEDGE;
        } else if (DUPS_OK_ACKNOWLEDGE_MODE.equals(acknowledgeMode)) {
            return Session.DUPS_OK_ACKNOWLEDGE;
        } else {
            return INVALID_ACKNOWLEDGE_MODE;
        }
    }

    /**
     * A helper method mostly for use in Dependency Injection containers which
     * allows you to customize the destination and destinationType properties
     * from a single ActiveMQDestination POJO
     */
    public void setActiveMQDestination(ActiveMQDestination destination) {
        setDestination(destination.getPhysicalName());
        if (destination instanceof Queue) {
            setDestinationType(Queue.class.getName());
        } else {
            setDestinationType(Topic.class.getName());
        }
    }

    /**
     * 
     */
    public ActiveMQDestination createDestination() {
        if (isEmpty(destinationType) || isEmpty(destination)) {
            return null;
        }

        ActiveMQDestination dest = null;
        if (Queue.class.getName().equals(destinationType)) {
            dest = new ActiveMQQueue(destination);
        } else if (Topic.class.getName().equals(destinationType)) {
            dest = new ActiveMQTopic(destination);
        } else {
            assert false : "Execution should never reach here";
        }
        return dest;
    }

    public String getMaxMessagesPerSessions() {
        return maxMessagesPerSessions;
    }

    /**
     * 
     */
    public void setMaxMessagesPerSessions(String maxMessagesPerSessions) {
        if (maxMessagesPerSessions != null) {
            this.maxMessagesPerSessions = maxMessagesPerSessions;
        }
    }

    public String getMaxSessions() {
        return maxSessions;
    }

    /**
     * 
     */
    public void setMaxSessions(String maxSessions) {
        if (maxSessions != null) {
            this.maxSessions = maxSessions;
        }
    }

    public String getUseRAManagedTransaction() {
        return useRAManagedTransaction;
    }

    /**
     * 
     */
    public void setUseRAManagedTransaction(String useRAManagedTransaction) {
        if (useRAManagedTransaction != null) {
            this.useRAManagedTransaction = useRAManagedTransaction;
        }
    }

    public int getMaxMessagesPerSessionsIntValue() {
        return Integer.parseInt(maxMessagesPerSessions);
    }

    public int getMaxSessionsIntValue() {
        return Integer.parseInt(maxSessions);
    }

    public boolean isUseRAManagedTransactionEnabled() {
        return Boolean.valueOf(useRAManagedTransaction).booleanValue();
    }

    public boolean getNoLocalBooleanValue() {
        return Boolean.valueOf(noLocal).booleanValue();
    }

    public String getEnableBatch() {
        return enableBatch;
    }

    /**
     * 
     */
    public void setEnableBatch(String enableBatch) {
        if (enableBatch != null) {
            this.enableBatch = enableBatch;
        }
    }

    public boolean getEnableBatchBooleanValue() {
        return Boolean.valueOf(enableBatch).booleanValue();
    }

    public int getMaxMessagesPerBatchIntValue() {
        return Integer.parseInt(maxMessagesPerBatch);
    }

    public String getMaxMessagesPerBatch() {
        return maxMessagesPerBatch;
    }

    /**
     * 
     */
    public void setMaxMessagesPerBatch(String maxMessagesPerBatch) {
        if (maxMessagesPerBatch != null) {
            this.maxMessagesPerBatch = maxMessagesPerBatch;
        }
    }

    public double getBackOffMultiplier() {
        if (redeliveryPolicy == null) {
            return 0;
        }
        return redeliveryPolicy.getBackOffMultiplier();
    }

    public long getInitialRedeliveryDelay() {
        if (redeliveryPolicy == null) {
            return 0;
        }
        return redeliveryPolicy.getInitialRedeliveryDelay();
    }

    public int getMaximumRedeliveries() {
        if (redeliveryPolicy == null) {
            return 0;
        }
        return redeliveryPolicy.getMaximumRedeliveries();
    }

    public boolean isUseExponentialBackOff() {
        if (redeliveryPolicy == null) {
            return false;
        }
        return redeliveryPolicy.isUseExponentialBackOff();
    }

    /**
     * 
     */
    public void setBackOffMultiplier(double backOffMultiplier) {
        lazyCreateRedeliveryPolicy().setBackOffMultiplier(backOffMultiplier);
    }
    
    public long getMaximumRedeliveryDelay() {
        if (redeliveryPolicy == null) {
            return 0;
        }
        return redeliveryPolicy.getMaximumRedeliveryDelay();
    }
    
    public void setMaximumRedeliveryDelay(long maximumRedeliveryDelay) {
        lazyCreateRedeliveryPolicy().setMaximumRedeliveryDelay(maximumRedeliveryDelay);
    }

    /**
     * 
     */
    public void setInitialRedeliveryDelay(long initialRedeliveryDelay) {
        lazyCreateRedeliveryPolicy().setInitialRedeliveryDelay(initialRedeliveryDelay);
        redeliveryPolicy.setRedeliveryDelay(initialRedeliveryDelay);
    }

    /**
     * 
     */
    public void setMaximumRedeliveries(int maximumRedeliveries) {
        lazyCreateRedeliveryPolicy().setMaximumRedeliveries(maximumRedeliveries);
    }

    /**
     * 
     */
    public void setUseExponentialBackOff(boolean useExponentialBackOff) {
        lazyCreateRedeliveryPolicy().setUseExponentialBackOff(useExponentialBackOff);
    }

    // don't use getter to avoid causing introspection errors in containers
    public RedeliveryPolicy redeliveryPolicy() {
        return redeliveryPolicy;
    }

    public RedeliveryPolicy lazyCreateRedeliveryPolicy() {
        if (redeliveryPolicy == null) {
            redeliveryPolicy = new RedeliveryPolicy();
        }
        return redeliveryPolicy;
    }
    
    public void setUseJndi(boolean useJndi) {
        this.useJndi = useJndi;
    }
    
    public boolean isUseJndi() {
        return useJndi;
    }

    public String getTrustStore() {
        if (!isEmpty(trustStore)) {
            return trustStore;
        }
        return null;
    }

    public void setTrustStore(String trustStore) {
        this.trustStore = trustStore;
    }

    public String getTrustStorePassword() {
        if (!isEmpty(trustStorePassword)) {
            return trustStorePassword;
        }
        return null;
    }

    public void setTrustStorePassword(String trustStorePassword) {
        this.trustStorePassword = trustStorePassword;
    }

    public String getKeyStore() {
        if (!isEmpty(keyStore)) {
            return keyStore;
        }
        return null;
    }

    public void setKeyStore(String keyStore) {
        this.keyStore = keyStore;
    }

    public String getKeyStorePassword() {
        if (!isEmpty(keyStorePassword)) {
            return keyStorePassword;
        }
        return null;
    }

    public void setKeyStorePassword(String keyStorePassword) {
        this.keyStorePassword = keyStorePassword;
    }

    public String getKeyStoreKeyPassword() {
        if (!isEmpty(keyStoreKeyPassword)) {
            return keyStoreKeyPassword;
        }
        return null;
    }

    public void setKeyStoreKeyPassword(String keyStoreKeyPassword) {
        this.keyStoreKeyPassword = keyStoreKeyPassword;
    }
}
