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

import com.sun.star.embed.*;

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

public class Test17 implements StorageTest {

	XMultiServiceFactory m_xMSF;
	XSingleServiceFactory m_xStorageFactory;
	TestHelper m_aTestHelper;

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

    public boolean test()
	{
		try
		{
			XStream xTempFileStream = m_aTestHelper.CreateTempFileStream( m_xMSF );
			if ( xTempFileStream == null )
				return false;

			// create storage based on the temporary stream
			Object pArgs[] = new Object[2];
			pArgs[0] = (Object) xTempFileStream;
			pArgs[1] = new Integer( ElementModes.WRITE );

			Object oTempStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
			XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
			if ( xTempStorage == null )
			{
				m_aTestHelper.Error( "Can't create temporary storage representation!" );
				return false;
			}


			byte pBytes1[] = { 1, 1, 1, 1, 1 };
            String pNames[] = { "SubStream1", "SubStream2", "SubStream3", "SubStream4", "SubStream5", "SubStream6", "SubStream7" };

            for ( int nInd = 0; nInd < pNames.length; nInd++ )
            {
			    // open a new substorage
			    XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
																	    "SubStorage1",
																	    ElementModes.WRITE );
			    if ( xTempSubStorage == null )
			    {
				    m_aTestHelper.Error( "Can't create substorage!" );
				    return false;
			    }

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

                // commit substorage first
                if ( !m_aTestHelper.commitStorage( xTempSubStorage ) )
                    return false;

                // dispose used storage to free resources
                if ( !m_aTestHelper.disposeStorage( xTempSubStorage ) )
                    return false;
            }

			// commit the root storage so the contents must be stored now
			if ( !m_aTestHelper.commitStorage( xTempStorage ) )
				return false;

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


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

			// close the output part of the temporary stream
			// the output part must present since we already wrote to the stream
			if ( !m_aTestHelper.closeOutput( xTempFileStream ) )
				return false;

			XInputStream xTempInStream = m_aTestHelper.getInputStream( xTempFileStream );
			if ( xTempInStream == null )
				return false;


			// open input stream
			// since no mode is provided the result storage must be opened readonly
			Object pOneArg[] = new Object[1];
			pOneArg[0] = (Object) xTempInStream;

			Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pOneArg );
			XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
			if ( xResultStorage == null )
			{
				m_aTestHelper.Error( "Can't open storage based on input stream!" );
				return false;
			}

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

            for ( int nInd = 0; nInd < pNames.length; nInd++ )
			    if ( !m_aTestHelper.checkStream( xResultSubStorage, pNames[nInd], "MediaType1", true, pBytes1 ) )
				    return false;

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

}
