/*
 * 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 features.bootstrapservices;

import java.util.Hashtable;

import flex.messaging.MessageDestination;
import flex.messaging.config.ConfigMap;
import flex.messaging.config.NetworkSettings;
import flex.messaging.config.ServerSettings;
import flex.messaging.config.ThrottleSettings;
import flex.messaging.config.ThrottleSettings.Policy;
import flex.messaging.services.AbstractBootstrapService;
import flex.messaging.services.Service;
import flex.messaging.services.messaging.adapters.JMSAdapter;
import flex.messaging.services.messaging.adapters.JMSSettings;

/**
 * This BootstrapService is used to dynamicaly create a Messaging Service along 
 * with its Messaging Destinations without the need for any configuration files.
 */
public class MessagingBootstrapService extends AbstractBootstrapService
{
    
    /**
     * Called by the <code>MessageBroker</code> after all of the server 
     * components are created but right before they are started. This is 
     * usually the place to create dynamic components.
     * 
     * @param id Id of the <code>AbstractBootstrapService</code>.
     * @param properties Properties for the <code>AbstractBootstrapService</code>. 
     */
    public void initialize(String id, ConfigMap properties)
    {
        Service messagingService = createService();
        createDestination1(messagingService);
        createDestination2(messagingService);
    }

    /**
     * Called by the <code>MessageBroker</code> as server starts. Useful for
     * custom code that needs to run after all the components are initialized
     * and the server is starting up. 
     */    
    public void start()
    {
        // No-op.
    }

    /**
     * Called by the <code>MessageBroker</code> as server stops. Useful for 
     * custom code that needs to run as the server is shutting down.
     */
    public void stop()
    {
        // No-op.
    }

    /*
    <?xml version="1.0" encoding="UTF-8"?>
    <service id="message-service" class="flex.messaging.services.MessageService">

    <!-- Example messaging-config.xml -->

    <adapters>
        <!--
           id: a unique id specifying the adapter
           class: the Flex Enterprise class which implements the adapter
             possible values: flex.messaging.services.messaging.adapters.ActionScriptAdapter
                              flex.messaging.services.messaging.adapters.JMSAdapter
                              coldfusion.flex.CFEventGatewayAdapter
           default: an optional attribute identifying the adapter to use when none is specified
        -->
        <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
        <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/>
     </adapters>
     */
    private Service createService()
    {
        String serviceId = "messaging-service";
        String serviceClass = "flex.messaging.services.MessageService";
        Service messageService = broker.createService(serviceId, serviceClass);

        messageService.registerAdapter("actionscript", "flex.messaging.services.messaging.adapters.ActionScriptAdapter");
        messageService.registerAdapter("jms", "flex.messaging.services.messaging.adapters.JMSAdapter");
        messageService.setDefaultAdapter("actionscript");

        return messageService;
    }

    /*
    <!-- Example ActionScriptAdapter destination -->
    <destination id="MyTopic">
        <properties>
            <network>
                <!--
                   Idle time in minutes for a subscriber to receive no messages
                   that triggers it to be automatically unsubscribed.
                   0 means don't force subscribers to unsubscribe automatically.
                   Default value is 0.
                -->
                <subscription-timeout-minutes>0</subscription-timeout-minutes>

                <!--
                   Throttling can be set up destination-wide as well as per-client. 
                   The inbound policy may be NONE, ERROR or IGNORE and the outbound policy may be NONE and IGNORE.
                   All throttle frequency values are considered the maximum allowed messages per second.
                   A frequency of 0 disables throttling altogether.
                -->
                <throttle-inbound policy="ERROR" max-frequency="0"/>
                <throttle-outbound policy="IGNORE" max-frequency="0"/>
            </network>

            <server>
                <!-- Max number of messages to maintain in memory cache -->
                <max-cache-size>1000</max-cache-size>

                <!-- message-time-to-live of 0 means live forever -->
                <message-time-to-live>0</message-time-to-live>

                <!-- 
                   The subtopic feature lets you divide the messages that a Producer component sends to a destination 
                   into specific categories at the destination.  You can configure a Consumer component that subscribes to 
                   the destination to receive only messages sent to a specific subtopic or set of subtopics.  You use 
                   wildcard characters (*) to send or receive messages from more than one subtopic.  The subtopic-separator 
                   element is optional; the default value is period
                -->
                <allow-subtopics>true</allow-subtopics>
                <subtopic-separator>.</subtopic-separator>

                <!-- 
                    Used to choose the algorithm for routing messages in a cluster.
                    When set to server-to-server (the default), subscriptions are 
                    broadcast through the cluster to ensure each server knows which 
                    destinations, subtopics, and selector expressions define subscriptions
                    for clients connected to other servers.  When a data message
                    arrives, it is then only sent to servers who have clients interested
                    in that message.  The other value for this setting "broadcast"
                    will simply broadcast all data messages to all servers.  In this
                    mode, subscribe/unsubscribe messages are not sent across the cluster
                -->
                <cluster-message-routing>server-to-server</cluster-message-routing>
            </server>
        </properties>

        <channels>
            <!--
               Set the ref id of the default channels to use as transport for this service.
               The channel is defined elsewhere using the channel-definition tag.
            -->
            <channel ref="my-polling-amf"/>
        </channels>
    </destination>
    */
    private void createDestination1(Service service)
    {
        String destinationId = "MyTopic";
        MessageDestination destination = (MessageDestination)service.createDestination(destinationId);
        
        NetworkSettings ns = new NetworkSettings();
        ns.setSubscriptionTimeoutMinutes(0);
        ThrottleSettings ts = new ThrottleSettings();
        ts.setInboundPolicy(Policy.ERROR);
        ts.setIncomingDestinationFrequency(0);
        ts.setOutboundPolicy(Policy.IGNORE);
        ts.setOutgoingDestinationFrequency(0);
        ns.setThrottleSettings(ts);
        destination.setNetworkSettings(ns);
        
        ServerSettings ss = new ServerSettings();
        ss.setMessageTTL(0);
        ss.setBroadcastRoutingMode("server-to-server");
        destination.setServerSettings(ss);

        destination.addChannel("my-polling-amf");
    }

    /*
    <!-- Example JMSAdapter destination -->
    <destination id="MyJMSTopic">
        <properties>
            <server>
                <!-- Optional. Default is false. This option is currently only used by JMS
                     adapter when the destination-type is Topic. In that case, durable JMS
                     consumers will be used by the JMS adapter. Note that this does not 
                     guarantee durability between Flex clients and JMS adapter but rather
                     between JMS adapter and JMS server.
                <durable>false</durable>
            </server>

            <!-- For specifics on JMS, please reference the Java Message Service specification or your J2EE server documentation -->
            <jms>
                <!--
                   This determines whether the adapter is performing topic (pub/sub) or queue (point-to-point) messaging.
                   This element is optional and defaults to Topic.

                <destination-type>Topic</destination-type>
                -->

                <!--
                   The name of the destination in JMS
                   This element is optional and defaults to the destination id

                <destination-name>FlexTopic</destination-name>
                -->

                <!--
                   The javax.jms.Message type which the adapter should use for this destination.
                   Supported types: javax.jms.TextMessage, javax.jms.ObjectMessage
                -->
                <message-type>javax.jms.TextMessage</message-type>

                <!-- The name of the JMS connection factory in JNDI -->
                <connection-factory>jms/flex/TopicConnectionFactory</connection-factory>

                <!-- The name of the destination in JNDI -->
                <destination-jndi-name>jms/topic/flex/simpletopic</destination-jndi-name>

                <!-- The JMS DeliveryMode for producers -->
                <delivery-mode>NON_PERSISTENT</delivery-mode>

                <!-- The JMS priority for messages sent by Flash producers -->
                <message-priority>DEFAULT_PRIORITY</message-priority>

                <!--
                   The message acknowledgement mode for the JMS adapter
                   None of these modes require any action on the part of the Flex messaging client.
                   Supported modes:
                     AUTO_ACKNOWLEDGE - the JMS provider client runtime automatically acknowledges the messages
                     DUPS_OK_ACKNOWLEDGE - auto-acknowledgement of the messages is not required
                     CLIENT_ACKNOWLEDGE - the JMS adapter should acknowledge that the message was received
                -->
                <acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>

                <!-- The JMS session transaction mode -->
                <transacted-sessions>false</transacted-sessions>
                
                <!--
                    The maximum number of producer proxies that this destination
                    should use when communicating with the JMS Server. The default
                    is 1 which implies all clients using this destinatin will
                    share the same connection to the JMS server.
                -->
                <max-producers>1</max-producers>
                
                <!-- (Optional) JNDI environment. Use when using JMS on a remote JNDI server. 
                Used to specify the JNDI environment to access an external JMS provider. 
                -->
                <initial-context-environment>
                    <property>
                        <name>Context.SECURITY_PRINCIPAL</name>
                        <value>anonymous</value>
                    </property>
                    <property>
                        <name>Context.SECURITY_CREDENTIALS</name>
                        <value>anonymous</value>
                    </property>
                    <property>
                        <name>Context.PROVIDER_URL</name>
                        <value>http://{server.name}:1856</value>
                    </property>
                    <property>
                        <name>Context.INITIAL_CONTEXT_FACTORY</name>
                        <value>fiorano.jms.runtime.naming.FioranoInitialContextFactory</value>
                    </property>
                </initial-context-environment>
            </jms>
        </properties>

        <channels>
            <channel ref="my-polling-amf"/>
        </channels>

        <security>
            <security-constraint ref="sample-users"/>
        </security>

        <adapter ref="jms"/>
    </destination>
     */
    private void createDestination2(Service service)
    {
        String destinationId = "MyJMSTopic";
        MessageDestination destination = (MessageDestination)service.createDestination(destinationId);

        ServerSettings ss = new ServerSettings();
        ss.setDurable(false);
        destination.setServerSettings(ss);

        String adapterId = "jms";
        JMSAdapter adapter = (JMSAdapter)destination.createAdapter(adapterId);

        // JMS settings are set at the adapter level
        JMSSettings jms = new JMSSettings();
        jms.setDestinationType("Topic");
        jms.setMessageType("javax.jms.TextMessage");
        jms.setConnectionFactory("jms/flex/TopicConnectionFactory");
        jms.setDestinationJNDIName("jms/topic/flex/simpletopic");
        jms.setDeliveryMode("NON_PERSISTENT");
        //jms.setMessagePriority(javax.jms.Message.DEFAULT_PRIORITY);
        jms.setAcknowledgeMode("AUTO_ACKNOWLEDGE");
        jms.setMaxProducers(1);
        Hashtable envProps = new Hashtable();
        envProps.put("Context.SECURITY_PRINCIPAL", "anonymous");
        envProps.put("Context.SECURITY_CREDENTIALS", "anonymous");
        envProps.put("Context.PROVIDER_URL", "http://{server.name}:1856");
        envProps.put("Context.INITIAL_CONTEXT_FACTORY", "fiorano.jms.runtime.naming.FioranoInitialContextFactory");
        jms.setInitialContextEnvironment(envProps);
        adapter.setJMSSettings(jms);

        destination.setSecurityConstraint("sample-users");

        destination.addChannel("my-polling-amf");
    }
}