/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/
package org.eclipse.birt.core.exception;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Enumeration;
import java.util.ResourceBundle;

import junit.framework.TestCase;

/**
 *
 */
public class BirtExceptionTest extends TestCase {

    private static String FATAL_ERROR_KEY = "Fatal_Error";
    private static String CONCATENATED_ERROR_KEY = "Recoverable_Error";
    private static String CONCATENATED_ERROR_ONE_ARG_KEY = "Recoverable_Error_One_Arg";    
    private static String fatalError = "A fatal error has happened. please contact system administrator.";
    private static String fatalErrorDE = "German: A fatal error has happened. please contact system administrator.";
    private static String concatenatedError = "A {0} error has happened. please contact {1}.";
    private static String concatenatedErrorDE = "German: A {0} error has happened. please contact {1}.";    
    private static String concatenatedErrorOneArg = "A fatal error has happened. please contact {0}.";
    private static String concatenatedErrorDEOneArg = "German: A fatal error has happened. please contact {0}.";
    private static final String TEST_PLUGIN_ID = "org.eclipse.birt.core";
 
  
    /*
     * @see TestCase#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();
    }

    /*
     * @see TestCase#tearDown()
     */
    protected void tearDown() throws Exception {
        super.tearDown();
    }
    
    public void testSerializeException( ) throws Exception
	{
		BirtException e = new BirtException( TEST_PLUGIN_ID, "ErrorCode",
				new MyResources( ) );
		ByteArrayOutputStream out = new ByteArrayOutputStream( );
		ObjectOutputStream oo = new ObjectOutputStream( out );
		oo.writeObject( e );
		ObjectInputStream oi = new ObjectInputStream( new ByteArrayInputStream(
				out.toByteArray( ) ) );
		BirtException re = (BirtException) oi.readObject( );
		assertEquals( TEST_PLUGIN_ID, re.getPluginId( ) );
		assertEquals( "ErrorCode", re.getErrorCode( ) );
	}
    
    public void testNoRBException( )
	{
		String errorCode = "No RB {0}";
		String error = "$NO-RB$ No RB Message";
		BirtException e = new BirtException( errorCode, "Message" );
		assertEquals( errorCode, e.getErrorCode( ) );
		assertEquals( error, e.getLocalizedMessage( ) );
		assertEquals( error, e.getMessage( ) );
	}
    
    public void testCorruptFormatException()
    {
		String errorCode = "No RB {0";
		String error = "$NO-RB$ No RB {0";
		BirtException e = new BirtException( errorCode, "Message" );
		assertEquals( errorCode, e.getErrorCode( ) );
		assertEquals( error, e.getLocalizedMessage( ) );
		assertEquals( error, e.getMessage( ) );
    }
    
    public void testBirtException()
    {
        // Tests for simple getters
        BirtException e1 = new BirtException(FATAL_ERROR_KEY, new MyResources());
        assertEquals( e1.getErrorCode(), FATAL_ERROR_KEY);
        assertEquals( e1.getLocalizedMessage(), fatalError);
        assertEquals( e1.getMessage(), fatalError);
        
        // Tests for localization
        BirtException e2 = new BirtException(FATAL_ERROR_KEY, new MyResources_de());
        assertEquals( e2.getLocalizedMessage(), fatalErrorDE);
        
        // Test for causes
        BirtException e3 = new BirtException(FATAL_ERROR_KEY, new MyResources_de(), e1);
        assertEquals( e3.getLocalizedMessage(), fatalErrorDE);
        assertEquals( e3.getCause().getLocalizedMessage(), fatalError);
        
        // Message formatting
        // Tests for simple getters
        BirtException e4 = new BirtException(CONCATENATED_ERROR_KEY, new Object[] {"fatal", "system administrator"}, new MyResources());
        assertEquals( e4.getErrorCode(), CONCATENATED_ERROR_KEY);
        assertEquals( e4.getLocalizedMessage(), fatalError);
        assertEquals( e4.getMessage(), fatalError);
        
        // Tests for localization
        BirtException e5 = new BirtException(CONCATENATED_ERROR_KEY, new Object[] {"fatal", "system administrator"}, new MyResources_de());
        assertEquals( e5.getLocalizedMessage(), fatalErrorDE);
        
        // Test for causes
        BirtException e6 = new BirtException(CONCATENATED_ERROR_KEY, new Object[] {"fatal", "system administrator"}, new MyResources_de(), e1);
        assertEquals( e6.getLocalizedMessage(), fatalErrorDE);
        assertEquals( e6.getCause().getLocalizedMessage(), fatalError);        

        // Message formatting
        // Tests for simple getters
        BirtException e7 = new BirtException(CONCATENATED_ERROR_ONE_ARG_KEY, (Object)"system administrator", new MyResources());
        assertEquals( e7.getErrorCode(), CONCATENATED_ERROR_ONE_ARG_KEY);
        assertEquals( e7.getLocalizedMessage(), fatalError);
        assertEquals( e7.getMessage(), fatalError);
        
        // Tests for localization
        BirtException e8 = new BirtException(CONCATENATED_ERROR_ONE_ARG_KEY, (Object)"system administrator", new MyResources_de());
        assertEquals( e8.getLocalizedMessage(), fatalErrorDE);
        
        // Test for causes
        BirtException e9 = new BirtException(CONCATENATED_ERROR_ONE_ARG_KEY, (Object)"system administrator", new MyResources_de(), e1);
        assertEquals( e9.getLocalizedMessage(), fatalErrorDE);
        assertEquals( e9.getCause().getLocalizedMessage(), fatalError);  
        
        // Test for plugin id
        BirtException e10 = new BirtException( TEST_PLUGIN_ID, CONCATENATED_ERROR_ONE_ARG_KEY, "system administrator" );
        assertEquals( TEST_PLUGIN_ID,e10.getPluginId( ) );          
    }
    
    // default (English language, United States)
    private class MyResources extends ResourceBundle {
        public Object handleGetObject(String key) {
            if (key.equals( FATAL_ERROR_KEY )) return fatalError;
            if (key.equals( CONCATENATED_ERROR_KEY)) return concatenatedError;
            if (key.equals( CONCATENATED_ERROR_ONE_ARG_KEY)) return concatenatedErrorOneArg;
            return null;
        }

        /* (non-Javadoc)
         * @see java.util.ResourceBundle#getKeys()
         */
        public Enumeration getKeys() {
            // TODO Auto-generated method stub
            return null;
        }
    }

    // German language
    private class MyResources_de extends MyResources {
        public Object handleGetObject(String key) {
            if (key.equals(FATAL_ERROR_KEY)) return fatalErrorDE;
            if (key.equals(CONCATENATED_ERROR_KEY)) return concatenatedErrorDE;
            if (key.equals( CONCATENATED_ERROR_ONE_ARG_KEY)) return concatenatedErrorDEOneArg;
            return null;
        }
    }

}
