/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view.model.jsp.persistence;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.osgi.framework.Version;

/**
 * The definitive index of what projects are indexed for JSP tag registry
 * persistence.
 * 
 * @author cbateman
 * 
 */
class MasterIndex implements Serializable
{
    public final static SerializableVersion CURRENT_VERSION  = new SerializableVersion(
                                                                     1, 0, 0);

    /**
     * 
     */
    private static final long               serialVersionUID = -2725662604972649316L;

    private final transient String          _repositoryPath;
    private final transient File            _storageFile;

    private IndexHeader                     _header;
    private List<ProjectIndex>              _projectIndices;

    public MasterIndex(final File storageFile, final String repositoryPath)
    {
        _storageFile = storageFile;
        _repositoryPath = repositoryPath;
    }

    public synchronized void create(final SerializableVersion version)
            throws IOException
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
        {
            JSFCoreTraceOptions.log("MasterIndex.create, version=:" //$NON-NLS-1$
                    + version.toString());
        }

        _header = new IndexHeader(version);
        _projectIndices = new ArrayList<ProjectIndex>();

        save(_storageFile);
    }

    public synchronized void save(final File file) throws IOException
    {
        FileOutputStream out = null;

        try
        {
            if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
            {
                JSFCoreTraceOptions.log("Trying to save master index file: " //$NON-NLS-1$
                        + file.getAbsolutePath());
            }

            out = new FileOutputStream(file);
            final ObjectOutputStream objStream = new ObjectOutputStream(out);
            objStream.writeObject(this);

            if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
            {
                JSFCoreTraceOptions
                        .log("Master index file written successfully: " //$NON-NLS-1$
                                + file.getAbsolutePath());
            }
        }
        finally
        {
            if (out != null)
            {
                out.close();
            }
        }
    }

    public synchronized void load(final SerializableVersion expectedVersion)
            throws IOException, ClassNotFoundException
    {
        FileInputStream in = null;

        try
        {
            if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
            {
                JSFCoreTraceOptions.log("Trying to load master index file: " //$NON-NLS-1$
                        + _storageFile.getAbsolutePath());
            }

            in = new FileInputStream(_storageFile);
            final ObjectInputStream objStream = new ObjectInputStream(in);
            MasterIndex index = (MasterIndex) objStream.readObject();
            _header = index._header;
            _projectIndices = index._projectIndices;

            if (JSFCoreTraceOptions.TRACE_JSPTAGPERSISTENCE)
            {
                JSFCoreTraceOptions
                        .log("Loaded master index file successfully:" //$NON-NLS-1$
                                + _storageFile.getAbsolutePath());
                JSFCoreTraceOptions.log("Initial contents: "); //$NON-NLS-1$
                System.out.println(index.toString());
            }
        }
        finally
        {
            if (in != null)
            {
                in.close();
            }
        }
    }

    public synchronized String toString()
    {
        StringBuffer buffer = new StringBuffer();

        buffer.append(String.format("Header: %s\n\n", _header.toString())); //$NON-NLS-1$

        for (final ProjectIndex projIndex : _projectIndices)
        {
            buffer.append(String.format("\t%s\n", projIndex.toString())); //$NON-NLS-1$
        }

        return buffer.toString();
    }

    public synchronized ProjectIndex getProjectIndex(final IProject project)
    {
        ProjectIndex index = findIndex(project);

        if (index != null)
        {
            return index;
        }

        // otherwise, create.
        index = new ProjectIndex(0, project.getName(), _repositoryPath);
        index.create();
        _projectIndices.add(index);
        try
        {
            save(_storageFile);
        }
        catch (IOException ioe)
        {
            JSFCorePlugin.log(ioe,
                    "Failed to save master index.  Project Index for " //$NON-NLS-1$
                            + project.toString() + " may not be saved"); //$NON-NLS-1$
        }
        return index;
    }

    public synchronized void removeProjectIndex(final IProject project) throws IOException
    {
        final ProjectIndex index = findIndex(project);
        if (index != null)
        {
            _projectIndices.remove(index);
            if (!index.remove())
            {
                throw new IOException("Failed to remove index file"); //$NON-NLS-1$
            }
        }
    }

    private ProjectIndex findIndex(final IProject project)
    {
        // check if the project already exists
        for (final ProjectIndex index : _projectIndices)
        {
            if (index.getProjectName().equals(project.getName()))
            {
                return index;
            }
        }
        return null;
    }

    private void writeObject(final java.io.ObjectOutputStream out)
            throws IOException
    {
        out.writeObject(_header);
        out.writeObject(_projectIndices);
    }

    private void readObject(final java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException
    {
        _header = (IndexHeader) in.readObject();
        _projectIndices = (List<ProjectIndex>) in.readObject();
    }

    private class IndexHeader implements Serializable
    {
        /**
         * serializable
         */
        private static final long         serialVersionUID = 40851054201507727L;

        private final SerializableVersion _version;
        private long                      _lastModifiedStamp;

        public IndexHeader(final SerializableVersion version)
        {
            _version = version;
            _lastModifiedStamp = 0;
        }

        protected final Version getVersion()
        {
            return _version.getVersion();
        }

        protected final synchronized long modified()
        {
            return _lastModifiedStamp++;
        }

        protected final synchronized long getLastModifiedStamp()
        {
            return _lastModifiedStamp;
        }

        public String toString()
        {
            return "Version: " + _version.toString(); //$NON-NLS-1$
        }
    }

    static class SerializableVersion implements Serializable
    {
        private Version           _version;
        /**
         * 
         */
        private static final long serialVersionUID = 5973410328814890568L;

        public SerializableVersion(final int major, final int minor,
                final int micro)
        {
            _version = new Version(major, minor, micro);
        }

        public SerializableVersion(final String versionString)
        {
            _version = new Version(versionString);
        }

        public Version getVersion()
        {
            return _version;
        }

        public String toString()
        {
            return _version.toString();
        }

        private void writeObject(ObjectOutputStream out) throws IOException
        {
            out.writeObject(_version.toString());
        }

        private void readObject(ObjectInputStream in) throws IOException,
                ClassNotFoundException
        {
            final String versionString = (String) in.readObject();
            _version = new Version(versionString);
        }
    }

    static class ProjectIndex implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = 2864798175910805380L;

        private final String      _projectName;
        private final String      _relativePath;
        private final long        _lastModStampOnProject;
        private File              _file;

        /**
         * @param lastModStampOnProject
         * @param projectName
         * @param relativePath
         */
        public ProjectIndex(final long lastModStampOnProject,
                final String projectName, final String relativePath)
        {
            super();
            _lastModStampOnProject = lastModStampOnProject;
            _projectName = projectName;
            _relativePath = relativePath;
        }

        public boolean remove()
        {
            return _file.delete();
        }

        public synchronized void create()
        {
            final long uniqueCode = Math
                    .round((Math.random() * Integer.MAX_VALUE));
            final String fileName = String.format("Project_%s_%x.idx", //$NON-NLS-1$
                    _projectName, Long.valueOf(uniqueCode));
            _file = new File(new Path(_relativePath).append(fileName)
                    .toOSString());
        }

        public synchronized Map<String, SerializableTLDNamespace> getNamespaces()
                throws IOException, ClassNotFoundException
        {
            FileInputStream in = null;

            try
            {
                in = new FileInputStream(_file);
                final ObjectInputStream objStream = new ObjectInputStream(in);
                final Map<String, SerializableTLDNamespace> namespaces = (Map<String, SerializableTLDNamespace>) objStream
                        .readObject();
                return namespaces;
            }
            catch (FileNotFoundException nfe)
            {
                return new HashMap<String, SerializableTLDNamespace>();
            }
            finally
            {
                if (in != null)
                {
                    in.close();
                }
            }
        }

        public synchronized void save(
                final Map<String, SerializableTLDNamespace> namespaces)
                throws IOException
        {
            FileOutputStream out = null;

            try
            {
                out = new FileOutputStream(_file);
                final ObjectOutputStream objStream = new ObjectOutputStream(out);
                objStream.writeObject(namespaces);
            }
            finally
            {
                if (out != null)
                {
                    out.close();
                }
            }
        }

        public String toString()
        {
            return "project= " + _projectName + ", relativePath=" //$NON-NLS-1$ //$NON-NLS-2$
                    + _relativePath + ", lastModified=" //$NON-NLS-1$
                    + _lastModStampOnProject + ", saveFile=" + _file; //$NON-NLS-1$
        }

        // public synchronized void save()
        // {
        // if (_file != null)
        // {
        // doSave();
        // }
        // throw new NullPointerException("_file is null");
        // }
        //
        // private void doSave() throws IOException
        // {
        // FileOutputStream out = null;
        //            
        // try
        // {
        // out = new FileOutputStream(_file);
        // final ObjectOutputStream objStream = new ObjectOutputStream(out);
        // objStream.writeObject(this);
        // }
        // finally
        // {
        // if (out != null)
        // {
        // out.close();
        // }
        // }
        // }

        protected final String getProjectName()
        {
            return _projectName;
        }

        protected final String getRelativePath()
        {
            return _relativePath;
        }

        protected final long getLastModStampOnProject()
        {
            return _lastModStampOnProject;
        }
    }
}
