/*******************************************************************************
 * 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=:"
                    + 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: "
                        + 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: "
                                + 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: "
                        + _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:"
                                + _storageFile.getAbsolutePath());
                JSFCoreTraceOptions.log("Initial contents: ");
                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()));

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

        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 "
                            + project.toString() + " may not be saved");
        }
        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");
            }
        }
    }

    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();
        }
    }

    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",
                    _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="
                    + _relativePath + ", lastModified="
                    + _lastModStampOnProject + ", saveFile=" + _file;
        }

        // 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;
        }
    }
}
