/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

package complex.storages;

import com.sun.star.uno.XInterface;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;

import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import com.sun.star.io.XStream;

import com.sun.star.embed.*;

import share.LogWriter;
import complex.storages.TestHelper;
import complex.storages.StorageTest;

public class Test05 implements StorageTest {

	XMultiServiceFactory m_xMSF;
	XSingleServiceFactory m_xStorageFactory;
	TestHelper m_aTestHelper;

	public Test05( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
	{
		m_xMSF = xMSF;
		m_xStorageFactory = xStorageFactory;
		m_aTestHelper = new TestHelper( aLogWriter, "Test05: " );
	}

    public boolean test()
	{
		try
		{
			String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
			if ( sTempFileURL == null || sTempFileURL == "" )
			{
				m_aTestHelper.Error( "No valid temporary file was created!" );
				return false;
			}

			// create temporary storage based on a previously created temporary file
			Object pArgs[] = new Object[2];
			pArgs[0] = (Object) sTempFileURL;
			pArgs[1] = new Integer( ElementModes.WRITE );

			Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
			XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
			if ( xTempFileStorage == null )
			{
				m_aTestHelper.Error( "Can't create storage based on temporary file!" );
				return false;
			}

			// open a new substorage
			XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempFileStorage,
																		"SubStorage1",
																		ElementModes.WRITE );
			if ( xTempSubStorage == null )
			{
				m_aTestHelper.Error( "Can't create substorage!" );
				return false;
			}

			// open a new substorage
			XStorage xSubSubStorage = m_aTestHelper.openSubStorage( xTempSubStorage,
																		"SubSubStorage1",
																		ElementModes.WRITE );
			if ( xSubSubStorage == null )
			{
				m_aTestHelper.Error( "Can't create substorage!" );
				return false;
			}

            byte pBigBytes[] = new byte[33000];
			for ( int nInd = 0; nInd < 33000; nInd++ )
				pBigBytes[nInd] = (byte)( nInd % 128 );

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
				return false;

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
				return false;

			byte pBytes1[] = { 1, 1, 1, 1, 1 };

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
				return false;

			byte pBytes2[] = { 2, 2, 2, 2, 2 };

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstream( xSubSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
				return false;

			// set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
			if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempFileStorage,
															"MediaType3",
															true,
															ElementModes.WRITE ) )
				return false;

			// set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
			if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
															"MediaType4",
															false,
															ElementModes.WRITE ) )
				return false;

			// set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
			if ( !m_aTestHelper.setStorageTypeAndCheckProps( xSubSubStorage,
															"MediaType5",
															false,
															ElementModes.WRITE ) )
				return false;


			// commit all the storages
			if ( !m_aTestHelper.commitStorage( xSubSubStorage ) )
				return false;

			if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
				return false;

			if ( !m_aTestHelper.commitStorage( xTempFileStorage ) )
				return false;

			// try to open an opened substorage, open call must fail
			if ( !m_aTestHelper.cantOpenStorage( xTempFileStorage, "SubStorage1" ) )
				return false;


			// reopen created streams
			XStream xSubStream1 = m_aTestHelper.OpenStream( xSubSubStorage,
															"SubStream1",
															ElementModes.WRITE | ElementModes.NOCREATE );
			XStream xBigSubStream1 = m_aTestHelper.OpenStream( xSubSubStorage,
															   "BigSubStream1",
															   ElementModes.WRITE | ElementModes.NOCREATE );
			XStream xSubStream2 = m_aTestHelper.OpenStream( xSubSubStorage,
															"SubStream2",
															ElementModes.READ | ElementModes.NOCREATE );
			XStream xBigSubStream2 = m_aTestHelper.OpenStream( xSubSubStorage,
															   "BigSubStream2",
															   ElementModes.READ | ElementModes.NOCREATE );

			if ( xSubStream1 == null || xBigSubStream1 == null || xSubStream2 == null || xBigSubStream2 == null )
				return false;

			// it should be possible to have more then one copy of stream for reading
			XStream xSubStream2clone = m_aTestHelper.OpenStream( xSubSubStorage,
																"SubStream2",
																ElementModes.READ | ElementModes.NOCREATE );
			XStream xBigSubStream2clone = m_aTestHelper.OpenStream( xSubSubStorage,
																    "BigSubStream2",
																    ElementModes.READ | ElementModes.NOCREATE );
			if ( xSubStream2clone == null || xBigSubStream2clone == null )
				return false;


			// so now the first streams can not be open neither for reading nor for writing
			if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.WRITE )
			  || !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream1", ElementModes.READ )
			  || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream1", ElementModes.WRITE )
			  || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream1", ElementModes.READ ) )
				return false;

			// the second streams can not be open for writing
			if ( !m_aTestHelper.cantOpenStream( xSubSubStorage, "SubStream2", ElementModes.WRITE )
			  || !m_aTestHelper.cantOpenStream( xSubSubStorage, "BigSubStream2", ElementModes.WRITE ) )
				return false;


			// dispose xTestSubStorage, all the subtree must be disposed
			if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
				return false;

			// check that subtree was disposed correctly
			try
			{
				xSubSubStorage.isStreamElement( "SubStream1" );
				m_aTestHelper.Error( "Substorage was not disposed!" );
				return false;
			}
			catch ( com.sun.star.lang.DisposedException de )
			{}
			catch ( Exception e )
			{
				m_aTestHelper.Error( "Wrong exception is thrown by disposed storage: " + e );
				return false;
			}

			try
			{
				xSubStream1.getInputStream();
				m_aTestHelper.Error( "Writeable substream was not disposed!" );
				return false;
			}
			catch ( com.sun.star.lang.DisposedException de )
			{}
			catch ( Exception e )
			{
				m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
				return false;
			}

			try
			{
				xSubStream2.getInputStream();
				m_aTestHelper.Error( "Readonly substream was not disposed!" );
				return false;
			}
			catch ( com.sun.star.lang.DisposedException de )
			{}
			catch ( Exception e )
			{
				m_aTestHelper.Error( "Wrong exception is thrown by disposed stream: " + e );
				return false;
			}


			// dispose root storage
			if ( !m_aTestHelper.disposeStorage( xTempFileStorage ) )
				return false;


			// ================================================
			// now check all the written and copied information
			// ================================================

			pArgs[1] = new Integer( ElementModes.READ );
			Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
			XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
			if ( xResultStorage == null )
			{
				m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
				return false;
			}

			if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.READ ) )
				return false;

			// open existing substorage
			XStorage xResSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
																	"SubStorage1",
																	ElementModes.READ );
			if ( xResSubStorage == null )
			{
				m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
				return false;
			}

			if ( !m_aTestHelper.checkStorageProperties( xResSubStorage, "MediaType4", false, ElementModes.READ ) )
				return false;

			// open existing substorage
			XStorage xResSubSubStorage = m_aTestHelper.openSubStorage( xResSubStorage,
																		"SubSubStorage1",
																		ElementModes.READ );
			if ( xResSubSubStorage == null )
			{
				m_aTestHelper.Error( "Can't open existing substorage 'SubSubStorage'!" );
				return false;
			}

			if ( !m_aTestHelper.checkStorageProperties( xResSubSubStorage, "MediaType5", false, ElementModes.READ ) )
				return false;

			// check substreams
			if ( !m_aTestHelper.checkStream( xResSubSubStorage, "SubStream1", "MediaType1", true, pBytes1 ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResSubSubStorage, "BigSubStream1", "MediaType1", true, pBigBytes ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResSubSubStorage, "SubStream2", "MediaType2", false, pBytes2 ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResSubSubStorage, "BigSubStream2", "MediaType2", false, pBigBytes ) )
				return false;

			// dispose used storages to free resources
			if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
				return false;

			return true;
		}
		catch( Exception e )
		{
			m_aTestHelper.Error( "Exception: " + e );
			return false;
		}
    }

}
