/**************************************************************
 * 
 * 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.embed.*;

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

public class Test09 implements StorageTest {

	XMultiServiceFactory m_xMSF;
	XSingleServiceFactory m_xStorageFactory;
	TestHelper m_aTestHelper;

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

    public boolean test()
	{
		try
		{
	
			// create temporary storage based on arbitrary medium
			// after such a storage is closed it is lost
			Object oTempStorage = m_xStorageFactory.createInstance();
			XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
			if ( xTempStorage == null )
			{
				m_aTestHelper.Error( "Can't create temporary storage representation!" );
				return false;
			}

			String sPass1 = "123";
			String sPass2 = "321";
			byte pBytes[] = { 1, 1, 1, 1, 1 };
            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
			// the stream will not be encrypted
			if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "SubStream1", "MediaType1", false, pBytes, sPass1 ) )
				return false;
            if ( !m_aTestHelper.WriteBytesToEncrSubstream( xTempStorage, "BigSubStream1", "MediaType1", false, pBigBytes, sPass1 ) )
				return false;

			// create temporary file
			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;
			}

			// copy xTempStorage to xTempFileStorage
			// xTempFileStorage will be automatically commited
			if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
				return false;

			// change password of the substream of new storage based on file
			int nResult = m_aTestHelper.ChangeStreamPass( xTempFileStorage, "SubStream1", sPass1, sPass2 );
			if ( nResult == 0 )
				return false; // test failed
			else if ( nResult == -1 )
				return true; // tested optional feature is not supported

			// change password of the substream of new storage based on file
			nResult = m_aTestHelper.ChangeStreamPass( xTempFileStorage, "BigSubStream1", sPass1, sPass2 );
			if ( nResult == 0 )
				return false; // test failed
			else if ( nResult == -1 )
				return true; // tested optional feature is not supported

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

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

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

			// the temporary file must not be locked any more after storage disposing
			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.checkEncrStream( xResultStorage, "SubStream1", "MediaType1", pBytes, sPass2 ) )
				return false;
			if ( !m_aTestHelper.checkEncrStream( xResultStorage, "BigSubStream1", "MediaType1", pBigBytes, sPass2 ) )
				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;
		}
    } 
}

