/******************************************************************************
 * Copyright (c) 2010 Oracle
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.wst.common.project.facet.core.internal;

import static org.eclipse.wst.common.project.facet.core.util.internal.DomUtil.elements;
import static org.eclipse.wst.common.project.facet.core.util.internal.DomUtil.root;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.util.internal.FileUtil;
import org.eclipse.wst.common.project.facet.core.util.internal.XmlWriter;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.w3c.dom.Element;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

public final class ProjectFacetPreferencesGroup
{
    private static final String PATH_IN_PROJECT 
        = ".settings/org.eclipse.wst.common.project.facet.core.prefs.xml"; //$NON-NLS-1$
    
    private static final String PATH_IN_WORKSPACE 
        = ".metadata/.plugins/org.eclipse.wst.common.project.facet.core/prefs.xml"; //$NON-NLS-1$
    
    private static final String EL_ROOT = "root"; //$NON-NLS-1$
    private static final String EL_FACET = "facet"; //$NON-NLS-1$
    private static final String EL_NODE = "node"; //$NON-NLS-1$
    private static final String EL_ATTRIBUTE = "attribute"; //$NON-NLS-1$
    private static final String ATTR_ID = "id"; //$NON-NLS-1$
    private static final String ATTR_NAME = "name"; //$NON-NLS-1$
    private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
    
    private final IFacetedProject project;
    private final LinkedHashMap<String,ProjectFacetPreferences> preferences;
    
    public ProjectFacetPreferencesGroup( final IFacetedProject project )
    
        throws BackingStoreException
        
    {
        this.project = project;
        this.preferences = new LinkedHashMap<String,ProjectFacetPreferences>();
        
        final InputStream in = getBackingFileContents();
        
        if( in != null )
        {
            try
            {
                final Reader reader
                    = new InputStreamReader( new BufferedInputStream( in ), XmlWriter.ENCODING );
                
                for( Element elFacet : elements( root( reader ), EL_FACET ) )
                {
                    final String facetId = elFacet.getAttribute( ATTR_ID );
                    final ProjectFacetPreferences root = new ProjectFacetPreferences( this, facetId, project );
                    
                    read( root, elFacet );
                    
                    this.preferences.put( facetId, root );
                }
            }
            catch( Exception e )
            {
                throw new BackingStoreException( e.getMessage(), e );
            }
            finally
            {
                try
                {
                    in.close();
                }
                catch( IOException e ) {}
            }
        }
    }
    
    public ProjectFacetPreferences getPreferences( final IProjectFacet facet )
    
        throws BackingStoreException
        
    {
        ProjectFacetPreferences prefs;
        
        synchronized( this )
        {
            final String facetId = facet.getId();
            prefs = this.preferences.get( facetId );
            
            if( prefs == null )
            {
                prefs = new ProjectFacetPreferences( this, facetId, this.project );
                this.preferences.put( facetId, prefs );
            }
        }
        
        return prefs;
    }
    
    public void removePreferences( final IProjectFacet facet )
    
        throws BackingStoreException
        
    {
        synchronized( this )
        {
            this.preferences.remove( facet.getId() );
        }
        
        save();
    }
    
    public void save()
    
        throws BackingStoreException
        
    {
        try
        {
            final File file = getBackingFile();
            StringWriter w = null;
            
            synchronized( this )
            {
                if( ! this.preferences.isEmpty() )
                {
                    w = new StringWriter();;
                    write( w );
                }
            }
            
            if( w == null )
            {
                FileUtil.deleteFile( file );
            }
            else
            {
                FileUtil.writeFile( file, w.toString() );
            }
        }
        catch( IOException e )
        {
            throw new BackingStoreException( e.getMessage(), e );
        }
        catch( CoreException e )
        {
            throw new BackingStoreException( e.getMessage(), e );
        }
    }
    
    private File getBackingFile()
    {
        final File file;
        
        if( this.project != null )
        {
            final IFile f = this.project.getProject().getFile( PATH_IN_PROJECT );
            file = f.getLocation().toFile();
        }
        else
        {
            final File wsroot = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile();
            file = new File( wsroot, PATH_IN_WORKSPACE );
        }
        
        return file;
    }
    
    private InputStream getBackingFileContents()
    
        throws BackingStoreException
        
    {
        InputStream in = null;
        
        if( this.project != null )
        {
            final IFile f = this.project.getProject().getFile( PATH_IN_PROJECT );
            
            if( f.exists() )
            {
                try
                {
                    in = f.getContents();
                }
                catch( CoreException e )
                {
                    throw new BackingStoreException( e.getMessage(), e );
                }
            }
        }
        else
        {
            final File wsroot = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile();
            final File file = new File( wsroot, PATH_IN_WORKSPACE );
            
            if( file.exists() )
            {
                try
                {
                    in = new FileInputStream( file );
                }
                catch( IOException e )
                {
                    throw new BackingStoreException( e.getMessage(), e );
                }
            }
        }
        
        return in;
    }
    
    private void read( final ProjectFacetPreferences preferences,
                       final Element node )
    {
        for( Element elAttr : elements( node, EL_ATTRIBUTE ) )
        {
            final String name = elAttr.getAttribute( ATTR_NAME );
            final String value = elAttr.getAttribute( ATTR_VALUE );
            preferences.put( name, value );
        }
        
        for( Element elNode : elements( node, EL_NODE ) )
        {
            final String name = elNode.getAttribute( ATTR_NAME );
            final ProjectFacetPreferences child = (ProjectFacetPreferences) preferences.node( name );
            read( child, elNode );
        }
    }
    
    private void write( final Writer w )
    
        throws IOException, BackingStoreException
        
    {
        final XmlWriter xml = new XmlWriter( w );
        
        xml.startElement( EL_ROOT );
        
        for( Map.Entry<String,ProjectFacetPreferences> entry : this.preferences.entrySet() )
        {
            xml.startElement( EL_FACET );
            xml.addAttribute( ATTR_ID, entry.getKey() );
            write( xml, entry.getValue() );
            xml.endElement();
        }
        
        xml.endElement();
        xml.flush();
    }
    
    private void write( final XmlWriter xml,
                        final Preferences preferences )
    
        throws IOException, BackingStoreException
        
    {
        for( String key : preferences.keys() )
        {
            xml.startElement( EL_ATTRIBUTE );
            xml.addAttribute( ATTR_NAME, key );
            xml.addAttribute( ATTR_VALUE, preferences.get( key, null ) );
            xml.endElement();
        }
        
        for( String childName : preferences.childrenNames() )
        {
            final Preferences child = preferences.node( childName );
            
            xml.startElement( EL_NODE );
            xml.addAttribute( ATTR_NAME, child.name() );
            write( xml, child );
            xml.endElement();
        }
    }
    
}
