package com.ibm.emb.test;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.util.Arrays;
import java.util.StringTokenizer;

import javax.ejb.CreateException;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.emb.ListenerVetoException;
import javax.emb.MediaException;
import javax.emb.MediaListener;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

import org.objectweb.jonas.emb.mfb.formats.image.JpegFormat;

import com.ibm.emb.junit.EMBStaticHelper;
import com.ibm.emb.junit.EMBTestCaseBase;
import com.ibm.emb.junit.EmbeddedMediaLocationInfo;
import com.ibm.emb.meb.test.ejb.MediaEntityLocalTestDriver;
import com.ibm.emb.meb.test.ejb.MediaEntityLocalTestDriverHome;

/**
 * <pre>
 * 
 *  
 *   
 *   
 *     Line Item: MEB API
 *     Subcategory 1: javax.emb
 *     Subcategory 2: MediaListener
 *   
 *    
 *   
 *  
 * </pre>
 */

public class MediaListenerTest extends EMBTestCaseBase {

    public MediaListenerTest(String name) throws MediaException {
        super(name);
    }

    private static String MEBTESTER_JNDI = "java:comp/env/ejb/MediaEntityLocalTestDriverHome";

    private InitialContext ic;

    private MediaEntityLocalTestDriverHome mebHome;

    private MediaEntityLocalTestDriver mebTester = null;

    /**
     * initialization of test case (called before each test method)
     */
    protected void setUp() throws RemoteException, CreateException {
        if (mebHome == null) {
            try {
                ic = new InitialContext();
                Object ojb = ic.lookup(MEBTESTER_JNDI);
                mebHome = (MediaEntityLocalTestDriverHome) PortableRemoteObject.narrow(ojb,
                        MediaEntityLocalTestDriverHome.class);
            } catch (NamingException ne) {
                System.out.println("NamingException thrown during setup. Msg: " + ne.getMessage());
            }
        }

        // create new instance of MediaEntityLocalTestDriver
        mebTester = mebHome.create();
        return;
    }

    /**
     * <pre>
     * 
     *  
     *   
     *   
     *     Testcase Name: handleAboutToChangeMediaEntity(String)
     *     Testcase Number: EMB142
     *   
     *     setup: create Media entity me and retrieve list of media listeners
     *     		  for each, call me1.addListener(listener) and run the following tests
     *   
     *     test procedure:
     *     1.call handleAboutToChangeMediaEntity(null)
     *       expected result: NullPointerException
     *   
     *     2.call me.setContent(valid content)
     *       expected result: no exception or ListenerVetoException
     *   
     *     3.call me.setDescription(random string)
     *       expected result: no exception or ListenerVetoException
     *   
     *     4.call me.setLocation(valid local location URL)
     *       expected result: no exception or ListenerVetoException
     *   
     *     5.call me.setMimeType(&quot;www/unknown&quot;)
     *       expected result: no exception or ListenerVetoException
     *   
     *     6.call me.setName(newName)
     *       expected result: no exception or ListenerVetoException
     *   
     *    
     *   
     *  
     * </pre>
     */
    public void testEMB142() throws IOException, InstantiationException, IllegalAccessException,
            ClassNotFoundException, FinderException, RemoteException, MediaException, CreateException, NamingException {

        mebTester.bindMediaFormat("jpg", new JpegFormat());

        EmbeddedMediaLocationInfo me1LocInfo = new EmbeddedMediaLocationInfo(embTestConfig.getJpgPictureName1());
        String me1 = mebTester.createMediaEntityBean();
        mebTester.setMediaEntityName(me1, me1LocInfo.getMediaName());
        mebTester.setMediaEntityContent(me1, me1LocInfo.getMediaFile());
        String description = mebTester.getMediaEntityDescription(me1);
        String mimeType = mebTester.getMediaEntityMimeType(me1);

        EmbeddedMediaLocationInfo me2LocInfo = new EmbeddedMediaLocationInfo(embTestConfig.getJpgPictureName2());
        String me2 = mebTester.createMediaEntityBean();
        mebTester.setMediaEntityName(me2, me2LocInfo.getMediaName());
        mebTester.setMediaEntityLocation(me2, me2LocInfo.getMediaURL());

        String mediaListeners = embTestConfig.getMediaListeners();
        StringTokenizer tokenizer = new StringTokenizer(mediaListeners, ";");
        String listenerName = null;
        MediaListener currentListener = null;

        while (tokenizer.hasMoreTokens()) {
            listenerName = tokenizer.nextToken();
            currentListener = (MediaListener) Class.forName(listenerName).newInstance();
            mebTester.addMediaEntityListener(me1, currentListener);

            int exception = -1;
            //
            // test 1
            //
            try {
                exception = mebTester.listenerAboutToChangeMEB(currentListener, me1, null);
            } catch (Throwable e) {
                fail("[" + listenerName + "] test 1: Should throw a NullPointerException but threw " + e.toString());
            }
            assertEquals("[" + listenerName + "] test 1: Should throw a NullPointerException",
                    MediaEntityLocalTestDriver.NULLPOINTER, exception);
            testTrace("[" + listenerName + "] test 1 passed");
            //
            // test 2
            //
            try {
                mebTester.setMediaEntityContent(me1, me2LocInfo.getMediaFile());
                testTrace("[" + listenerName + "] test 2 passed");
            } catch (ListenerVetoException e) {
                assertTrue("[" + listenerName + "] test 2: content changed", Arrays.equals(
                        getByteArrayFromFile(me1LocInfo.getMediaFile()), mebTester.getMediaEntityContent(me1)));
                testTrace("[" + listenerName + "] test 2 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 2: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 3
            //
            try {
                mebTester.setMediaEntityDescription(me1, EMBStaticHelper.createRandomString(EMBStaticHelper.randomInt(
                        0, 10)));
                testTrace("[" + listenerName + "] test 3 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 3: description changed", description, mebTester
                        .getMediaEntityDescription(me1));
                testTrace("[" + listenerName + "] test 3 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 3: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 4
            //
            try {
                mebTester.setMediaEntityLocation(me2, me1LocInfo.getMediaURL());
                testTrace("[" + listenerName + "] test 4 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 4: location changed", me2LocInfo.getMediaURL(), mebTester
                        .getMediaEntityLocation(me2));
                testTrace("[" + listenerName + "] test 4 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 4: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 5
            //
            try {
                mebTester.setMediaEntityMimeType(me1, "www/unknown");
                testTrace("[" + listenerName + "] test 5 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 5: mimeType changed", mimeType, mebTester
                        .getMediaEntityMimeType(me1));
                testTrace("[" + listenerName + "] test 5 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 5: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 6
            //
            try {
                mebTester.setMediaEntityName(me1, "newName.jpg");
                testTrace("[" + listenerName + "] test 6 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 6: name changed", me1LocInfo.getMediaName(), mebTester
                        .getMediaEntityName(me1));
                testTrace("[" + listenerName + "] test 6 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 6: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
        }
        succeed();
    }

    /**
     * Testcase Name: handleMediaEntityChanged(String) Testcase Number: EMB143
     * setup: create Media entity me and retrieve list of media listeners for
     * each, call me1.addListener(listener) and run the following tests test
     * procedure: 1.call handleMediaEntityChanged(null) expected result:
     * NullPointerException 2.call me.setContent(valid content) expected result:
     * no exception or ListenerVetoException 3.call me.setDescription(random
     * string) expected result: no exception or ListenerVetoException 4.call
     * me.setLocation(valid local location URL) expected result: no exception or
     * ListenerVetoException 5.call me.setMimeType("www/unknown") expected
     * result: no exception or ListenerVetoException 6.call me.setName(newName)
     * expected result: no exception or ListenerVetoException
     */
    public void testEMB143() throws IOException, InstantiationException, IllegalAccessException,
            ClassNotFoundException, FinderException, RemoteException, MediaException, CreateException, NamingException {

        mebTester.bindMediaFormat("jpg", new JpegFormat());

        EmbeddedMediaLocationInfo me1LocInfo = new EmbeddedMediaLocationInfo(embTestConfig.getJpgPictureName1());
        String me1 = mebTester.createMediaEntityBean();
        mebTester.setMediaEntityName(me1, me1LocInfo.getMediaName());
        mebTester.setMediaEntityContent(me1, me1LocInfo.getMediaFile());
        String description = mebTester.getMediaEntityDescription(me1);
        String mimeType = mebTester.getMediaEntityMimeType(me1);

        EmbeddedMediaLocationInfo me2LocInfo = new EmbeddedMediaLocationInfo(embTestConfig.getJpgPictureName2());
        String me2 = mebTester.createMediaEntityBean();
        mebTester.setMediaEntityName(me2, me2LocInfo.getMediaName());
        mebTester.setMediaEntityLocation(me2, me2LocInfo.getMediaURL());

        String mediaListeners = embTestConfig.getMediaListeners();
        StringTokenizer tokenizer = new StringTokenizer(mediaListeners, ";");
        String listenerName = null;
        MediaListener currentListener = null;

        while (tokenizer.hasMoreTokens()) {
            listenerName = tokenizer.nextToken();
            currentListener = (MediaListener) Class.forName(listenerName).newInstance();
            mebTester.addMediaEntityListener(me1, currentListener);

            int exception = -1;
            //
            // test 1
            //
            try {
                exception = mebTester.listenerMediaEntityChanged(currentListener, me1, null);
            } catch (Throwable e) {
                fail("[" + listenerName + "] test 1: Should throw a NullPointerException but threw " + e.toString());
            }
            assertEquals("[" + listenerName + "] test 1: Should throw a NullPointerException",
                    MediaEntityLocalTestDriver.NULLPOINTER, exception);
            testTrace("[" + listenerName + "] test 1 passed");
            //
            // test 2
            //
            try {
                mebTester.setMediaEntityContent(me1, me2LocInfo.getMediaFile());
                testTrace("[" + listenerName + "] test 2 passed");
            } catch (ListenerVetoException e) {
                assertTrue("[" + listenerName + "] test 2: content changed", Arrays.equals(
                        getByteArrayFromFile(me1LocInfo.getMediaFile()), mebTester.getMediaEntityContent(me1)));
                testTrace("[" + listenerName + "] test 2 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 2: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 3
            //
            try {
                mebTester.setMediaEntityDescription(me1, EMBStaticHelper.createRandomString(EMBStaticHelper.randomInt(
                        0, 10)));
                testTrace("[" + listenerName + "] test 3 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 3: description changed", description, mebTester
                        .getMediaEntityDescription(me1));
                testTrace("[" + listenerName + "] test 3 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 3: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 4
            //
            try {
                mebTester.setMediaEntityLocation(me2, me1LocInfo.getMediaURL());
                testTrace("[" + listenerName + "] test 4 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 4: location changed", me2LocInfo.getMediaURL(), mebTester
                        .getMediaEntityLocation(me2));
                testTrace("[" + listenerName + "] test 4 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 4: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 5
            //
            try {
                mebTester.setMediaEntityMimeType(me1, "www/unknown");
                testTrace("[" + listenerName + "] test 5 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 5: mimeType changed", mimeType, mebTester
                        .getMediaEntityMimeType(me1));
                testTrace("[" + listenerName + "] test 5 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 5: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
            //
            // test 6
            //
            try {
                mebTester.setMediaEntityName(me1, "newName.jpg");
                testTrace("[" + listenerName + "] test 6 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 6: name changed", me1LocInfo.getMediaName(), mebTester
                        .getMediaEntityName(me1));
                testTrace("[" + listenerName + "] test 6 passed: threw ListenerVetoException");
            } catch (Exception e) {
                fail("[" + listenerName + "] test 6: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
        }
        succeed();
    }

    /**
     * <pre>
     * 
     *  
     *   
     *   
     *     Testcase Name: handleAboutToRemoveMediaEntity(MediaEntityLocal)
     *     Testcase Number: EMB144
     *   
     *     setup:
     *   
     *     test procedure:
     *     1.call handleAboutToRemoveMediaEntity(null)
     *       expected result: NullPointerException
     *   
     *     2.try to remove media entity
     *       expected result: no exception or ListenerVetoException
     *     					  if ListenerVetoException, check media entity was not removed
     *   
     *    
     *   
     *  
     * </pre>
     */
    public void testEMB144() throws MalformedURLException, IOException, MediaException, CreateException,
            InstantiationException, IllegalAccessException, ClassNotFoundException, RemoteException, NamingException,
            FinderException, RemoveException {
        EmbeddedMediaLocationInfo me1LocInfo = new EmbeddedMediaLocationInfo(embTestConfig.getJpgPictureName1());
        String me1 = null;

        String mediaListeners = embTestConfig.getMediaListeners();
        StringTokenizer tokenizer = new StringTokenizer(mediaListeners, ";");
        String listenerName = null;
        MediaListener currentListener = null;

        while (tokenizer.hasMoreTokens()) {
            me1 = mebTester.createMediaEntityBean();
            mebTester.setMediaEntityName(me1, me1LocInfo.getMediaName());
            mebTester.setMediaEntityContent(me1, me1LocInfo.getMediaFile());

            listenerName = tokenizer.nextToken();
            currentListener = (MediaListener) Class.forName(listenerName).newInstance();
            mebTester.addMediaEntityListener(me1, currentListener);

            int exception = -1;
            //
            // test 1
            //
            try {
                exception = mebTester.listenerAboutToRemoveMEB(currentListener, null);
            } catch (Throwable e) {
                fail("[" + listenerName + "] test 1 threw " + e.toString());
            }
            assertEquals("test 1: Should throw a NullPointerException", MediaEntityLocalTestDriver.NULLPOINTER,
                    exception);
            testTrace("[" + listenerName + "] test 1 passed");
            //
            // test 2
            //
            try {
                mebTester.removeMEBExceptions(me1);
                testTrace("[" + listenerName + "] test 2 passed");
            } catch (ListenerVetoException e) {
                assertEquals("[" + listenerName + "] test 2: media entity removed", me1, mebTester
                        .findMEBByPrimaryKey(me1));
                testTrace("[" + listenerName + "] test 2 passed");
                mebTester.removeMediaEntityListener(me1, currentListener);
                mebTester.removeMEBByPK(me1);
            } catch (Exception e) {
                fail("[" + listenerName + "] test 2: Should pass or throw ListenerVetoException but threw "
                        + e.toString());
            }
        }
        succeed();
    }
}