/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cuni.amis.pogamut.base.utils.logging.jmx;

import cz.cuni.amis.pogamut.base.exceptions.PogamutException;
import cz.cuni.amis.pogamut.base.utils.Pogamut;
import cz.cuni.amis.pogamut.base.utils.logging.ILogCategories;
import cz.cuni.amis.pogamut.base.utils.logging.LogCategories;
import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.concurrent.CountDownLatch;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * Exports ILogCategories through JMX and then tests receiving messages over the JMX.
 * @author Ik
 */
public class JMXLoggingTest {

    public JMXLoggingTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    CountDownLatch messageReceivedLatch = new CountDownLatch(1);
    String receivedMessage = null;
    
    // TODO add test methods here.
    // The methods must be annotated with annotation @Test. For example:
    //
    @Test
    public void receiveLogEventThroughJMX() throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, PogamutException, MalformedURLException, IOException, InterruptedException, MBeanException, InstanceNotFoundException, AttributeNotFoundException, ReflectionException {
        final String msg = "TEST LOG MESSAGE FROM receiveLogEventThroughJMX()";
        // export the log on the MBean server
        ILogCategories logCategories = new LogCategories();
        LogCategory log = logCategories.getCategory("testLogCategory");
        JMXLogCategories jmxLogCategories = new JMXLogCategories(logCategories, 
                Pogamut.getPlatform().getMBeanServer(),
                "testDomain",""); // use empty hierarchical type
                //Thread.sleep(1000000);
        // connect through RMI and get the proxy
        MBeanServerConnection mbsc = Pogamut.getPlatform().getMBeanServerConnection();
        ObjectName logCatsName = ObjectName.getInstance("testDomain:name=logCategories,type=logging");
        // get the name of the only one category
        String[] catNames = (String[]) mbsc.getAttribute(logCatsName, "CategoryNames");
        // get the object name for this category
        String testCategoryName = (String) mbsc.invoke(logCatsName,
                "getJMXCategoryName",
                catNames, new String[] {"java.lang.String"});
        // add the listener
        mbsc.addNotificationListener(ObjectName.getInstance(testCategoryName), new NotificationListener() {

            public void handleNotification(Notification notification, Object handback) {
                receivedMessage = notification.getMessage();
                messageReceivedLatch.countDown();
            }
        }, null, this);
        
        // send log event
        log.info(msg);
        // wait
        messageReceivedLatch.await();
        // compare
        assertTrue(receivedMessage.contains(msg));
    }
}