/*******************************************************************************
 * 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.report.model.writer;

import java.io.FileOutputStream;
import java.io.OutputStream;

import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.util.DocumentUtil;
import org.eclipse.birt.report.model.core.DesignElement;
import org.eclipse.birt.report.model.elements.interfaces.IReportDesignModel;
import org.eclipse.birt.report.model.util.BaseTestCase;
import org.eclipse.birt.report.model.util.ReportDesignSerializer;

/**
 * Tests the document related serialization.
 */

public class DocumentUtilTest extends BaseTestCase
{

	/**
	 * Design file name, which tests the element property value localization.
	 */

	private static final String DESIGN_WITH_ELEMENT_EXTENDS = "DocumentUtilTest.xml"; //$NON-NLS-1$

	/**
	 * Design file name, which tests the lib reference with library structures.
	 */

	private static final String DESIGN_WITH_STRUCTURE_REFERENCE = "DocumentUtilTest_1.xml"; //$NON-NLS-1$

	/**
	 * Design file name, which tests indirect element reference of library
	 * elements by inheritance.
	 */

	private static final String DESIGN_WITH_INDIRECT_REFERENCE = "DocumentUtilTest_2.xml"; //$NON-NLS-1$

	/**
	 * Design file name. Tests the shared style's name must not become element's
	 * name.
	 */

	private static final String DESIGN_WITH_SHARED_STYLE = "DocumentUtilTest_3.xml"; //$NON-NLS-1$

	/**
	 * Design file name.
	 */

	private static final String DESIGN_WITH_EXTERNAL_SELECTORS = "DocumentUtilTest_4.xml"; //$NON-NLS-1$

	/**
	 * Tests the element property value localization.
	 * 
	 * @throws Exception
	 */

	public void testSerializeWithElementExtends( ) throws Exception
	{
		openDesign( DESIGN_WITH_ELEMENT_EXTENDS );
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeNonLineBreakDocument( os );
		assertTrue( compareTextFile(
				"DocumentUtilTest_golden.xml", "DocumentUtilTest_out.xml" ) ); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the lib reference of embedded images.
	 * 
	 * @throws Exception
	 */

	public void testSerializeWithLibReference( ) throws Exception
	{
		openDesign( DESIGN_WITH_STRUCTURE_REFERENCE );
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out_1.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );
		assertTrue( compareTextFile(
				"DocumentUtilTest_golden_1.xml", "DocumentUtilTest_out_1.xml" ) ); //$NON-NLS-1$//$NON-NLS-2$
	}

	/**
	 * Tests the indirect element references by inheritances during the
	 * serialization.
	 * 
	 * @throws Exception
	 */

	public void testSerializeWithIndirectRef( ) throws Exception
	{
		openDesign( DESIGN_WITH_INDIRECT_REFERENCE );
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out_2.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );
		assertTrue( compareTextFile(
				"DocumentUtilTest_golden_2.xml", "DocumentUtilTest_out_2.xml" ) ); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the serlization of template elements.
	 * 
	 * @throws Exception
	 */

	public void testTemplate( ) throws Exception
	{
		openDesign( "TemplateElementParserTest.xml" ); //$NON-NLS-1$
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out_3.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );
		assertTrue( compareTextFile(
				"DocumentUtilTest_golden_3.xml", "DocumentUtilTest_out_3.xml" ) ); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * when serialize report design, the embedded image from library should be
	 * copied locally.
	 * 
	 * @throws Exception
	 */
	public void testSerializeWithEmbeddedImage( ) throws Exception
	{
		openDesign( "TestSerializeEmbeddeImage.xml" ); //$NON-NLS-1$
		assertNotNull( designHandle );
		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out_EmbeddedImage.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );

		assertTrue( compareTextFile(
				"DocumentUtilTest_golden_4.xml", "DocumentUtilTest_out_EmbeddedImage.xml" ) ); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/**
	 * when there is a external resource file sets for this report, all report
	 * properties use the external string value should be saved into the report
	 * file after serialization. And the reource key should be set to null.
	 * 
	 * @throws Exception
	 * 
	 */
	public void testSerializeExternalString( ) throws Exception
	{
		openDesign( "DocumnetUtilTest_ExternalResource.xml" ); //$NON-NLS-1$
		assertNotNull( designHandle );
		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_out_ExternalResource.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );

		assertTrue( compareTextFile(
				"DocumentUtilTest_golden_5.xml", "DocumentUtilTest_out_ExternalResource.xml" ) ); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/**
	 * If two non-named element refers the same shared style, their names should
	 * not be style names.
	 * 
	 * @throws Exception
	 */

	public void testSerializeWithSharedStyle( ) throws Exception
	{
		openDesign( DESIGN_WITH_SHARED_STYLE );
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_shared_style_out.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );

		assertTrue( compareTextFile(
				"DocumentUtilTest_shared_style_golden.xml", //$NON-NLS-1$
				"DocumentUtilTest_shared_style_out.xml" ) ); //$NON-NLS-1$
	}

	/**
	 * If two non-named element refers the same shared style, their names should
	 * not be style names.
	 * 
	 * @throws Exception
	 */

	public void testSerializeExternalSelectors( ) throws Exception
	{
		openDesign( DESIGN_WITH_EXTERNAL_SELECTORS );
		assertNotNull( designHandle );

		String fileName = getClassFolder( ) + OUTPUT_FOLDER
				+ "DocumentUtilTest_external_selectors_out.xml"; //$NON-NLS-1$
		FileOutputStream os = new FileOutputStream( fileName );
		serializeDocument( os );

		// make sure that selectors in the library are in the namespace of the
		// design

		DesignElement localizedStyle = design.getNameSpace(
				IReportDesignModel.STYLE_SLOT ).getElement( "table-footer" ); //$NON-NLS-1$
		assertNotNull( localizedStyle );
		
		assertTrue( compareTextFile(
				"DocumentUtilTest_external_selectors_golden.xml", //$NON-NLS-1$
				"DocumentUtilTest_external_selectors_out.xml" ) ); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.util.BaseTestCase#tearDown()
	 */

	protected void tearDown( ) throws Exception
	{
		designHandle = null;

		super.tearDown( );
	}

	/**
	 * Writes the document to the internal output stream.
	 * 
	 * @throws Exception
	 */

	private void serializeDocument( OutputStream os ) throws Exception
	{
		ReportDesignSerializer visitor = new ReportDesignSerializer( );
		designHandle.getModule( ).apply( visitor );

		design = visitor.getTarget( );
		designHandle = (ReportDesignHandle) design.getHandle( design );

		designHandle.serialize( os );

		os.close( );
	}

	/**
	 * Writes the document to the internal output stream.
	 * 
	 * @throws Exception
	 */

	private void serializeNonLineBreakDocument( OutputStream os )
			throws Exception
	{
		DocumentUtil.serialize( designHandle, os );
		os.close( );
	}

}
