/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2004 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): ____________________________________.
 * Contributor(s): ______________________________________.
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

// SampleAppliClient.java
//

package sampleappli;

import java.rmi.RemoteException;
import java.util.Enumeration;
import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

/**
 *
 */
public class SampleAppliClient {

    static Context initialContext = null;

    static EnvHome home = null;

    // Number of second to wait before the checking process
    static int sleepSecond = 10;

    public static void main(String[] args) {

        // Initialize the number of second to wait before the checking process
        if (args.length > 0) {
            sleepSecond = (new Integer(args[0])).intValue();
        }

        // Get InitialContext
        try {
            initialContext = new InitialContext();
        } catch (NamingException e) {
            e.printStackTrace();
            System.exit(2);
        }

        // Lookup bean home
        String beanName = "EnvHome";
        try {
            home = (EnvHome) PortableRemoteObject.narrow(initialContext.lookup(beanName), EnvHome.class);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }

        // Init the environment for the application
        Env env = null;
        try {
            env = home.create();
            env.init();
        } catch (Exception ex) {
            System.err.println("Cannot init Environment: " + ex);
            System.exit(2);
        }

        TopicConnectionFactory tcf = null;
        TopicPublisher tp = null;
        Topic topic = null;
        // JNDI name of the Topics
        String topicName = "StockHandlerTopic";
        // JNDI name of the connection factory
        String conFactName = "JTCF";

        try {
            // lookup the TopicConnectionFactory through its JNDI name
            tcf = (TopicConnectionFactory) initialContext.lookup(conFactName);
            // lookup the Topic through its JNDI name
            topic = (Topic) initialContext.lookup(topicName);
        } catch (NamingException e) {
            e.printStackTrace();
            System.exit(2);
        }

        TopicConnection tc = null;
        TopicSession session = null;
        try {
            tc = tcf.createTopicConnection();
            session = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
            tp = session.createPublisher(topic);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }

        MapMessage mess = null;
        int nbmess = 0;
        // We send several messages that will update the database and the file
        // order
        try {
            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer10");
            mess.setString("ProductId", "00003");
            mess.setInt("Quantity", 3);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer1");
            mess.setString("ProductId", "00001");
            mess.setInt("Quantity", 5);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer3");
            mess.setString("ProductId", "00002");
            mess.setInt("Quantity", 2);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer2");
            mess.setString("ProductId", "00004");
            mess.setInt("Quantity", 6);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer2");
            mess.setString("ProductId", "00003");
            mess.setInt("Quantity", 10);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer3");
            mess.setString("ProductId", "00001");
            mess.setInt("Quantity", 10);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer1");
            mess.setString("ProductId", "00002");
            mess.setInt("Quantity", 5);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer10");
            mess.setString("ProductId", "00004");
            mess.setInt("Quantity", 3);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer122");
            mess.setString("ProductId", "00003");
            mess.setInt("Quantity", 6);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer45");
            mess.setString("ProductId", "00001");
            mess.setInt("Quantity", 4);
            tp.publish(mess);
            nbmess++;

            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer7");
            mess.setString("ProductId", "00002");
            mess.setInt("Quantity", 2);
            tp.publish(mess);
            nbmess++;

            // Here we send a message that will force the rollback of the
            // transaction
            // in the onMessage of StockHandler MessageDrivenBean
            mess = session.createMapMessage();
            mess.setString("CustomerId", "customer00");
            mess.setString("ProductId", "00000");
            mess.setInt("Quantity", 1000);
            tp.publish(mess);
            session.close();
            tc.close();

        } catch (Exception ex) {
            System.err.println("Exception caught when sending messages: " + ex);
            System.exit(2);
        }

        // Before the checking process we wait a little ....
        try {
            Thread.currentThread().sleep(1000 * sleepSecond);
        } catch (InterruptedException e) {
            System.err.println("InterruptedException");
            System.exit(2);
        }

        // We have to check that nbmess have actually sent to the Message driven
        // bean Order
        // this is done by reading the order file (order.txt), it must have
        // nbmess lines
        BufferedReader inorderbr = null;
        try {
            File f = new File(System.getProperty("java.io.tmpdir") + File.separator + System.getProperty("user.name")
                    + "_order.txt");
            DataInputStream inorder = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
            inorderbr = new BufferedReader(new InputStreamReader(inorder));
        } catch (Exception ex) {
            System.err.println("Cannot open the order file: " + ex);
            System.exit(2);
        }

        String s = null;
        int n = 0;
        try {
            while ((s = inorderbr.readLine()) != null) {
                n++;
                System.out.println(s);
            }
            inorderbr.close();
        } catch (java.io.IOException ex) {
            System.err.println("cannot read the order file: " + ex);
        }
        if (n == nbmess) {
            System.out.println("Nb messages sent and received OK");
        } else {
            System.out.println("Problem: nb messages sent = " + nbmess + ", nb messages received = " + n);
            System.out.println("         (re-run SampleAppliClent with an argument greater than " + sleepSecond + ")");
        }

        // Lookup bean home
        String stockbeanName = "StockHome";
        StockHome shome = null;
        Enumeration listOfStocks = null;
        try {
            shome = (StockHome) PortableRemoteObject.narrow(initialContext.lookup(stockbeanName), StockHome.class);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }

        try {
            listOfStocks = shome.findAllStocks();
        } catch (Exception e) {
            System.err.println("Cannot findAllStocks: " + e);
        }
        Stock stock = null;
        try {
            while (listOfStocks.hasMoreElements()) {
                stock = (Stock) listOfStocks.nextElement();
                String id = stock.getId();
                int qty = stock.getQuantity();
                System.out.println("StockId = " + id + " Quantity = " + qty);
                if (id.equals("00000")) {
                    if (qty != 10) {
                        System.err.println("Problem: Stock id 00000 must be set to 10");
                        System.out.println("         (re-run SampleAppliClent with an argument greater than "
                                + sleepSecond + ")");
                        System.exit(2);
                    }
                } else {
                    // for the other id the stock quantity must be equals to 1
                    if (qty != 1) {
                        System.err.println("Problem: Stock id " + id + " must be set to 1");
                        System.out.println("         (re-run SampleAppliClent with an argument greater than "
                                + sleepSecond + ")");
                        System.exit(2);
                    }
                }
            }
        } catch (Exception ex) {
            System.err.println("Exception caught while reading stocks: " + ex);
        }

        System.out.println("SampleApplicationClient   OK");

    }
}