// AlarmGenerator.java

package org.objectweb.alarm;

import java.rmi.RemoteException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.jms.*;

class ClientThread extends Thread {
    String name;

    public ClientThread(int num) {
	name = AlarmGenerator.m_device;
	if (name == null) {
	    name = "device"+num;
	}
	setName(name);
    }

    /**
     * random returns an integer between 0 and max - 1
     */
    private int random(int max) {

	double d = Math.random();
	int ret = (int) (max * d);
	return ret;
    }

    private String getReason(int sev) {
	String reason;
	int num = AlarmGenerator.m_mess;
	if (num == 0) {
	    num = random(10) + 1;
	}
	switch (sev) {
	case 1:
	    reason = "Severe Error "+num;
	    break;
	case 2:
	    reason = "Warning "+num;
	    break;
	case 3:
	    reason = "Running OK";
	    break;
	default:
	    reason = "Unknown Alarm";
	    break;
	}
	return reason;
    }

    public void run() {

	// Create Session + Publisher
	TopicSession session = null;
	TopicPublisher tp = null;
	try {
	    session = AlarmGenerator.mytc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);	
	    tp = session.createPublisher(AlarmGenerator.mytopic);
	 } catch (Exception e) {
	    System.err.println("Cannot create JMS Publisher:"+ e);
	}

	// main loop
	int severity = AlarmGenerator.m_severity;
	try {
	    for (int i = 0; i < AlarmGenerator.m_loops; i++) {
		// publish messages to the topic
		try {
		    MapMessage message = session.createMapMessage();
		    // randomize the severity level if not specified
		    if (severity == 0)
			severity = random(2)+1;
		    message.setInt("Severity", severity);
		    message.setString("From", name);
		    message.setString("Reason", getReason(severity));
		    tp.publish(message);
		} catch (JMSException e) {
		    System.err.println("Exception occurred: "+ e);
		}
	    }
	} catch (Exception e) {
	    System.err.println("Exception in main loop"+ e);
	}
    }
}


public class AlarmGenerator { 

    static Context ictx = null;
    static Topic mytopic = null;
    static TopicConnection mytc = null;


    static boolean m_reinit = false;
    static int m_threads = 1;
    static int m_loops = 1;
    static int m_severity = 0;
    static int m_mess = 0;
    static String m_device = null;

    private static void usage() {
	System.out.println("AlarmGenerator [-d device] [-l loops] [-t threads] [-s severity] [-m num]");
    }

    public static void main(String[] args) {

	TopicConnectionFactory tcf = null;

	// Get Args
	// Get command args
	for (int argn = 0; argn < args.length; argn++) {
	    String s_arg = args[argn];
	    Integer i_arg;
	    if (s_arg.equals("-l")) {
		s_arg = args[++argn];
		i_arg = java.lang.Integer.valueOf(s_arg);
		m_loops = i_arg.intValue();
	    } else if (s_arg.equals("-d")) {
		m_device = args[++argn];
	    } else if (s_arg.equals("-t")) {
		s_arg = args[++argn];
		i_arg = java.lang.Integer.valueOf(s_arg);
		m_threads = i_arg.intValue();
	    } else if (s_arg.equals("-s")) {
		s_arg = args[++argn];
		i_arg = java.lang.Integer.valueOf(s_arg);
		m_severity = i_arg.intValue();;
	    } else if (s_arg.equals("-m")) {
		s_arg = args[++argn];
		i_arg = java.lang.Integer.valueOf(s_arg);
		m_mess = i_arg.intValue();
	    } else {
		usage();
		System.exit(2);
	    }
	}

	// Get InitialContext
	try {
	    ictx = new InitialContext();
	} catch (NamingException e) {
	    System.err.println("Cannot get InitialContext:"+ e);
	}

	// Lookup JMS resources
	try {
	    // lookup the TopicConnectionFactory through its JNDI name
	    tcf = (TopicConnectionFactory) ictx.lookup("JTCF");
	    // lookup the Topic through its JNDI name
	    mytopic = (Topic) ictx.lookup("AlarmTopic");
	} catch (NamingException e) {
	    System.err.println("Cannot lookup JMS Resources:"+ e);
	}

	// Create Connection
	try {
	    mytc = tcf.createTopicConnection();
	 } catch (Exception e) {
	    System.err.println("Cannot create JMS Connection:"+ e);
	}

	// If reinit: send a special message to reinit AlarmTable first.
	// This doesn't work (DuplicateKey exception)
	// Code to remove!
	if (m_reinit) {
	    TopicSession session = null;
	    TopicPublisher tp = null;
	    MapMessage message;
	    try {
		session = AlarmGenerator.mytc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);	
		tp = session.createPublisher(AlarmGenerator.mytopic);
		message = session.createMapMessage();
		message.setInt("Severity", 1);
		message.setString("From", "reinit");
		message.setString("Reason", "reinit");
		tp.publish(message);
	    } catch (JMSException e) {
		System.err.println("Exception occurred: "+ e);
	    } finally {
		try {
		    session.close();
		} catch (Exception i) {}
	    }
	}

	// Create and start threads
	ClientThread[] t_thr = new ClientThread[m_threads];
	for (int i = 0; i < m_threads; i++) {
	    t_thr[i] = new ClientThread(i+1);
	    t_thr[i].start();
	}

	// Wait end of all threads
	for (int p = 0; p < m_threads; p++) {
	    try {
		t_thr[p].join();
	    } catch (InterruptedException e) {
		System.err.println("ERROR: Problem in ClientThread.join"+ e);
	    }
	}

	// close connection
	try {
	    mytc.close();
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}
