import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 *
 * @author David Rodriguez A.
 * 
 */
public class Reactor implements Runnable {
    private Connection connection;
    private ActiveMQConnectionFactory connectionFactory;
    private String name;//nombre del reactor
    private String queueName;//nombre de la cola del reactor
    private boolean status;
    private Session session;
    private Destination dest;
    private Destination dest_client;
    private Destination Ctrl;
    private MessageProducer producer;
    private MessageProducer toclient_producer;
    private MessageConsumer consumer;
    

    
    public Reactor(String name){
        this.init(name);
       //Creando Listener para escuchar los comandos que vengan desde el cliente
       ControlListener listen = new ControlListener(connectionFactory,this);
       new Thread(listen,this.name+" listener").start();
    }
    
    private void init(String name){
        this.name = name;
        this.queueName="DataQueue:"+name;
        this.status=true;
        connectionFactory = new ActiveMQConnectionFactory("system", "manager", "tcp://localhost:61616");     
    }

    public boolean updateParam(int val) throws SQLException {
        boolean retorno = false;
        try {
            connection = connectionFactory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

             //cola donde el reactor almacenara los valores de temperatura y presion
            dest = session.createQueue(this.queueName);
            dest_client=session.createQueue("Client"+this.queueName);
            Ctrl = session.createQueue("ControlQueue:"+this.name);

             //Objeto producer para enviar datos a la cola destino ( productor )
            producer = session.createProducer(dest);
            
            //cola para que el cliente vea los datos
            toclient_producer = session.createProducer(this.dest_client);
            
            consumer = session.createConsumer(Ctrl);

            //TextMessage message = session.createTextMessage(mensaje);
            MapMessage msg = session.createMapMessage();
            msg.setString("Name",this.name);
            //msg.setString("Status","Alive");
            msg.setInt("Temperature", val);
            msg.setFloat("Pressure", (float) (val * 0.65));
            //msg.setInt("Pressure",val*2);

            //enviando parametros a la cola
            producer.send(msg);
            //enviando parametros a la cola del cliente
            toclient_producer.send(msg);
            toclient_producer.close();
            producer.close();
            session.close();
            connection.close();
            retorno = true;
        }catch (JMSException ex){
            retorno = true;
            System.out.println(ex.getMessage());
        }
        return retorno;
    }

     public void run() {
        try {
           System.out.println("(Reactor.java) "+this.name+" is running...");
            
           while(true){
               if(status){
                int val = (int)(Math.random() * 60) + 1;
                System.out.println("Inserting "+val+" in -> " +this.queueName);
                updateParam(val);
                Thread.sleep(5000); //esperando 5 segundos
               }else{
                   updateParam(0);
                   Thread.sleep(5000); //esperando 5 segundos
               }
           }
        } catch (InterruptedException ex) {
            Logger.getLogger(Reactor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Reactor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

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

     public boolean getStatus(){
        return this.status;
     }
     public void changeStatus(){
        this.status=!status;
        System.out.println("("+this.name+ ") status: "+ status);
     }
     
     public static void main(String[] args) {
        Reactor reactor  = new Reactor("reactor1");
        Reactor reactor2 = new Reactor("reactor2");
        Reactor reactor3 = new Reactor("reactor3");
        new Thread(reactor,"reactor1").start();
        new Thread(reactor2,"reactor2").start();
        new Thread(reactor3,"reactor3").start();
    }

}
