/**************************************************************
 * 
 * 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 com.sun.star.script.framework.container;

import com.sun.star.script.framework.log.LogUtils;
import com.sun.star.script.framework.provider.PathUtils;
import com.sun.star.script.framework.io.XOutputStreamWrapper;
import com.sun.star.script.framework.io.XInputStreamWrapper;

import java.util.Map;
import java.util.HashMap;
import java.io.OutputStream;
import java.io.InputStream;

import com.sun.star.uno.XComponentContext;

import com.sun.star.uno.UnoRuntime;

import com.sun.star.io.XOutputStream;
import com.sun.star.io.XTruncate;

import com.sun.star.deployment.XPackage;
import com.sun.star.deployment.ExtensionRemovedException;

public class UnoPkgContainer extends ParcelContainer
{

    private Map registeredPackages = new HashMap();
    protected String extensionDb;
    protected String extensionRepository;

    public UnoPkgContainer(  XComponentContext xCtx, String locationURL, 
            String _extensionDb, String _extensionRepository, String language ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
    {
        super( xCtx, locationURL, language, false );
        extensionDb = _extensionDb;
        extensionRepository = _extensionRepository;
        init();
    }

    // gets the ParcelContainer for persisted uno packages
    public ParcelContainer getRegisteredUnoPkgContainer( String url )
    {
        if (!url.endsWith("/"))
        {
            url += "/";
        }

        LogUtils.DEBUG("** getRegisterPackage ctx = " + containerUrl  );
        LogUtils.DEBUG("** getRegisterPackage  for uri " + url );
        LogUtils.DEBUG("** getRegisterPackage  for langugage " + language );
        ParcelContainer result = (ParcelContainer)registeredPackages.get( url ); 
        LogUtils.DEBUG("getRegisterPackage result is  " + result );
        return result;
    }

    public boolean hasRegisteredUnoPkgContainer( String url )
    {
        boolean result = false;
        if ( getRegisteredUnoPkgContainer( url ) != null )
        {
            result = true;
        }
        return result;
    }

    private void registerPackageContainer( String url, ParcelContainer c )
    {
        if (!url.endsWith("/"))
        {
            url += "/";
        }

        LogUtils.DEBUG("RegisterPackage ctx = " + containerUrl  );
        LogUtils.DEBUG("RegisterPackage language = " + language  );
        LogUtils.DEBUG("RegisterPackage " + c + " for url " + url );
        registeredPackages.put( url, c );
    }

    public void deRegisterPackageContainer( String url )
    {
        if (!url.endsWith("/"))
        {
            url += "/";
        }

        LogUtils.DEBUG("In deRegisterPackageContainer for " + url );
        if ( hasRegisteredUnoPkgContainer( url ) )
        {
            try
            {
                DeployedUnoPackagesDB db = getUnoPackagesDB();
                if ( db != null )
                {
                    if ( db.removePackage( language, url ) )
                    {
                        writeUnoPackageDB( db );
                        ParcelContainer container = 
                            ( ParcelContainer ) registeredPackages.get( url );
                        if ( !container.hasElements() )
                        {
                           // When all libraries within a package bundle
                           // ( for this language ) are removed also
                           // remove the container from its parent 
                           // Otherwise, a container ( with no containees )
                           // representing the uno package bundle will
                           // still exist and so will get displayed
                           if ( container.parent() != null )
                           {
                               container.parent().removeChildContainer( container );
                           }
                       }
                       registeredPackages.remove( url );
                   }
               }
           }
           catch (Exception e)
           {
               //TODO revisit exception handling and exception here
               //means something very wrong
               LogUtils.DEBUG("***** deRegisterPackageContainer() got exception " + e );
           }
        }
        LogUtils.DEBUG("Leaving deRegisterPackageContainer for " + url );
    }

    private void init() throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
    {
        LogUtils.DEBUG("getting container for  " + containerUrl );
        DeployedUnoPackagesDB db =  null;
        try
        {    
            db = getUnoPackagesDB();
            if ( db != null )
            {
                String[] packages = db.getDeployedPackages( language );

                for ( int i=0; i<packages.length;i++)
                {
                    try
                    {
                        processUnoPackage( packages[i], language );
                    }
                    catch ( com.sun.star.lang.IllegalArgumentException ila)
                    {
                        LogUtils.DEBUG("Failed to process " +  packages[i] + " for " + language);
                        LogUtils.DEBUG("   Reason: " + ila );
                    }
                    catch( Exception e )
                    {
                        // TODO proper exception or do we wish
                        // to ignore errors here
                        LogUtils.DEBUG("Something very wrong!!!!!");
                        LogUtils.DEBUG("Failed to process " +  packages[i] + " for " + language);
                        LogUtils.DEBUG("   Reason: " + e );
                    }
                }
            }
        }
        catch ( com.sun.star.lang.WrappedTargetException e )
        {
            // no deployed packages
           LogUtils.DEBUG("No deployed uno-packages for " + containerUrl );
        }
    }


    public ScriptMetaData findScript( ParsedScriptUri psu ) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException

    {
        ScriptMetaData scriptData = null; 

        String language = psu.language;
        String functionName = psu.function;
        String parcelName = psu.parcel;
        String location = psu.location;

        LogUtils.DEBUG("*** UnoPkgContainer.findScript() ***" +
            "\ncontainerUrl = " + containerUrl + 
            "\nfunction = " + functionName + 
            "\nlocation = " + location + 
            "\nparcel = " + parcelName );

        ParcelContainer pc = getChildContainer( location ); 

        if (  pc  == null )
        {
            throw new com.sun.star.lang.WrappedTargetException( "Failed to resolve script " , null, new com.sun.star.lang.IllegalArgumentException( "Cannot resolve script location for script = " + functionName ) );
        }

        scriptData = pc.findScript( psu );
        return scriptData;

    }

    private DeployedUnoPackagesDB getUnoPackagesDB() throws com.sun.star.lang.WrappedTargetException
    {
        InputStream is = null;
        DeployedUnoPackagesDB dp = null;
        try
        {
//            String path = containerUrl.substring( 0, containerUrl.lastIndexOf("/") );
            String packagesUrl = PathUtils.make_url( extensionDb, "/Scripts/" + extensionRepository + "-extension-desc.xml" );
            LogUtils.DEBUG("getUnoPackagesDB() looking for existing db in " + packagesUrl );
            if ( m_xSFA.exists( packagesUrl ) )
            {
                if ( packagesUrl.startsWith( "vnd.sun.star.tdoc" ) )
                {
                    // handles using XStorage directly
                    throw new com.sun.star.lang.WrappedTargetException("Can't handle documents yet");
                }

                is = new XInputStreamWrapper( m_xSFA.openFileRead( packagesUrl ) );
                dp = new DeployedUnoPackagesDB( is );
                try
                {
                    is.close();
                    is = null;
                }
                catch ( Exception ignore )
                {
                }
            }
            else
            {
                LogUtils.DEBUG("getUnoPackagesDB() " + packagesUrl + " does not exist");
            } 
        }
        catch( Exception e )
        {
            LogUtils.DEBUG("getUnoPackagesDB() caught Exception: " + e  );
            LogUtils.DEBUG( LogUtils.getTrace( e ) );
            throw new com.sun.star.lang.WrappedTargetException( e.toString());
        }
        finally
        {
            if ( is != null )
            {
                try
                {
                    is.close();
                    is = null;
                }
                catch ( Exception ignore )
                {
                }
            }
        } 

        return dp;
    }
    
    private  void writeUnoPackageDB( DeployedUnoPackagesDB dp ) throws com.sun.star.lang.IllegalArgumentException,  com.sun.star.lang.WrappedTargetException
    {
        LogUtils.DEBUG("In writeUnoPackageDB() ");

        XOutputStream xos = null;
        OutputStream os = null;
        try
        {
//            String path = containerUrl.substring( 0, containerUrl.lastIndexOf("/") );
            String packagesUrl = PathUtils.make_url( extensionDb, "/Scripts/" + extensionRepository + "-extension-desc.xml" );
            xos =  m_xSFA.openFileWrite( packagesUrl );
            XTruncate xTrc = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xos );
            if (  xTrc != null )
            {
                LogUtils.DEBUG("In writeUnoPackageDB() Truncating...." );
                xTrc.truncate();
            }
            else
            {
                LogUtils.DEBUG("In writeUnoPackageDB() CAN'T Truncate...." );
            }
            os = new XOutputStreamWrapper( xos );
            dp.write( os );
            try
            {
                os.close(); // will close xos
                os = null;
            }
            catch( Exception ignore )
            {
            }
        }
        catch( Exception e )
        {
            LogUtils.DEBUG("In writeUnoPackageDB() Exception: " + e  );
            throw new com.sun.star.lang.WrappedTargetException( e.toString());
        }
        finally
        {
            if ( os != null )
            {
                try
                {
                    os.close(); // will close xos
                    os = null;
                }
                catch ( Exception ignore )
                {
                }
            }
        } 
    }

    public  void processUnoPackage( XPackage dPackage, String language ) throws com.sun.star.lang.IllegalArgumentException,  com.sun.star.lang.WrappedTargetException, com.sun.star.container.ElementExistException
    {
        LogUtils.DEBUG("** in processUnoPackage " ); 	
        String uri = null;
        DeployedUnoPackagesDB db = null;
        uri =  dPackage.getURL();

        if ( !uri.endsWith( "/" ) )
        {
            uri += "/";
        }

        LogUtils.DEBUG("** processUnoPackage getURL() -> " + uri ); 	
        LogUtils.DEBUG("** processUnoPackage getName() -> " + dPackage.getName() ); 	
        LogUtils.DEBUG("** processUnoPackage getMediaType() -> " + dPackage.getPackageType().getMediaType() );
        try
        {
            LogUtils.DEBUG("** processUnoPackage getDisplayName() -> " + dPackage.getDisplayName() );
        }
        catch (com.sun.star.deployment.ExtensionRemovedException e)
        {
            throw new com.sun.star.lang.WrappedTargetException(e.toString(), this, e);
        }
        
        processUnoPackage( uri, language );

        db = getUnoPackagesDB();
        if ( db == null )
        {
            try
            {
                db = new DeployedUnoPackagesDB();
            }
            catch ( java.io.IOException ioe )
            {
                throw new com.sun.star.lang.WrappedTargetException( ioe.toString());
            }
        }
        db.addPackage( language, uri );
        writeUnoPackageDB( db );
    }

    private  void processUnoPackage( String uri, String language ) throws com.sun.star.lang.IllegalArgumentException,  com.sun.star.lang.WrappedTargetException, com.sun.star.container.ElementExistException
    {
        if ( hasRegisteredUnoPkgContainer( uri ) )
        {
            throw new com.sun.star.container.ElementExistException( "Already a registered uno package " + uri + " for language " + language );
        }
        LogUtils.DEBUG("processUnoPackage - URL = " + uri );
        LogUtils.DEBUG("processUnoPackage - script library package");
        String parentUrl = uri;

        if ( uri.indexOf( "%2Funo_packages%2F" ) > -1 ||
             uri.indexOf( "/uno_packages/" ) > -1 ||
             uri.indexOf("$UNO_USER_PACKAGES_CACHE/") > -1 ||
             uri.indexOf("$UNO_SHARED_PACKAGES_CACHE/") > -1 ||
             uri.indexOf("$BUNDLED_EXTENSIONS/") > -1 )
        {
            //its in a bundle need to determine the uno-package file its in                    
            LogUtils.DEBUG("processUnoPackage - is part of a uno bundle");

            int index = uri.lastIndexOf("/");
            if ( uri.endsWith("/") )
            {
                uri = uri.substring( 0, index );
                index = uri.lastIndexOf("/");
            }

            if ( index > -1 )
            {                    
                parentUrl = uri.substring( 0, index  );
                LogUtils.DEBUG("processUnoPackage - composition is contained in " + parentUrl);
            }

            ParcelContainer pkgContainer = getChildContainerForURL( parentUrl );
            if ( pkgContainer == null )
            {
                pkgContainer = new ParcelContainer( this, m_xCtx, parentUrl, language, false );
                if ( pkgContainer.loadParcel( uri ) == null )
                {
                    throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library from composition package " + uri + " for language " + language );

                }
                addChildContainer( pkgContainer );
            }
            else
            {
                if ( pkgContainer.loadParcel( uri ) == null )
                {
                    throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library from composition package " + uri + " for language " + language );
                }

            }
            registerPackageContainer( uri,  pkgContainer );
        }
        else
        {
            // stand-alone library package, e.g. not contained in
            // an uno package
            if ( loadParcel( uri ) == null )
            {
                throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library package " + uri + " for language " + language );
            }
            registerPackageContainer( uri, this );
        }

    }

}
