/*******************************************************************************
 * Copyright (c) 2004 IBM 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.snippets.internal.palette;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import org.eclipse.core.runtime.Platform;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.wst.common.snippets.core.ISnippetCategory;
import org.eclipse.wst.common.snippets.core.ISnippetItem;
import org.eclipse.wst.common.snippets.core.ISnippetVariable;
import org.eclipse.wst.common.snippets.core.ISnippetsEntry;
import org.eclipse.wst.common.snippets.internal.Logger;
import org.eclipse.wst.common.snippets.internal.PluginRecord;
import org.eclipse.wst.common.snippets.internal.SnippetDefinitions;
import org.eclipse.wst.common.snippets.internal.SnippetsPlugin;
import org.eclipse.wst.common.snippets.internal.util.CommonXML;
import org.eclipse.wst.common.snippets.internal.util.StringUtils;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class UserModelDumper {

	private static UserModelDumper dumper = null;

	public synchronized static UserModelDumper getInstance() {
		if (dumper == null) {
			dumper = new UserModelDumper();
		}
		return dumper;
	}

	protected UserModelDumper() {
		super();
	}

	/**
	 * Save the properties known for ISnippetsEntry
	 */
	protected void assignEntryProperties(ISnippetsEntry entry, Element owningElement) {
		if (entry instanceof SnippetPaletteDrawer) {
			owningElement.setAttribute(SnippetsPlugin.NAMES.ID, ((SnippetPaletteDrawer) entry).getId());
			if (((SnippetPaletteDrawer) entry).getSmallIconName() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.ICON, ((SnippetPaletteDrawer) entry).getSmallIconName());
			if (entry.getLabel() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.LABEL, entry.getLabel());
			if (((SnippetPaletteDrawer) entry).getLargeIconName() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.LARGEICON, ((SnippetPaletteDrawer) entry).getLargeIconName());
		}
		if (entry instanceof SnippetPaletteItem) {
			owningElement.setAttribute(SnippetsPlugin.NAMES.ID, ((SnippetPaletteItem) entry).getId());
			if (((SnippetPaletteItem) entry).getSmallIconName() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.ICON, ((SnippetPaletteItem) entry).getSmallIconName());
			if (entry.getLabel() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.LABEL, entry.getLabel());
			if (((SnippetPaletteItem) entry).getLargeIconName() != null)
				owningElement.setAttribute(SnippetsPlugin.NAMES.LARGEICON, ((SnippetPaletteItem) entry).getLargeIconName());
		}
		owningElement.appendChild(createDescription(owningElement.getOwnerDocument(), entry.getDescription()));
	}

	/**
	 * If the ISnippetsEntry has a PluginRecord, save the plugin information
	 */
	protected void assignSourceFor(ISnippetsEntry entry, Element owningElement) {
		if (entry.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_PLUGINS) {
			PluginRecord record = (PluginRecord) entry.getSourceDescriptor();
			owningElement.setAttribute(SnippetsPlugin.NAMES.PLUGIN, record.getPluginName());
			owningElement.setAttribute(SnippetsPlugin.NAMES.VERSION, record.getPluginVersion());
		}
		else if (entry.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_WORKSPACE) {
			owningElement.setAttribute(SnippetsPlugin.NAMES.SHARED, SnippetsPlugin.NAMES.SHARED);
		}
	}

	/**
	 * Create and save the properties known for LibraryCategories
	 */
	protected Element createCategory(Document doc, ISnippetCategory category) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.CATEGORY);
		assignSourceFor(category, element);
		// if the category came from a plugin, only store a placeholder
		// to maintain the ordering [it will be reloaded in subsequent
		// sessions directly from the plugin definitions]
		element.setAttribute(SnippetsPlugin.NAMES.ID, ((SnippetPaletteDrawer) category).getId());
		if (category instanceof PaletteDrawer) {
			element.setAttribute(SnippetsPlugin.NAMES.INITIAL_STATE, Integer.toString(((PaletteDrawer) category).getInitialState()));
		}
		String[] filters = category.getFilters();
		if (filters.length > 0) {
			String filtersAttr = filters[0];
			if (filters.length > 1) {
				for (int i = 1; i < filters.length; i++) {
					filtersAttr += " " + filters[i]; //$NON-NLS-1$
				}
			}
			element.setAttribute("filters", filtersAttr); //$NON-NLS-1$
		}
		if (category.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_USER) {
			assignEntryProperties(category, element);

			for (int i = 0; i < category.getItems().length; i++) {
				ISnippetItem item = category.getItems()[i];
				Element child = createItem(doc, item);
				element.appendChild(child);
			}
		}

		if (Logger.DEBUG_DEFINITION_PERSISTENCE)
			System.out.println("User item writer saving category " + ((SnippetPaletteDrawer) category).getId()); //$NON-NLS-1$
		return element;
	}

	/**
	 * Create and save the content property of a ISnippetItem - always place
	 * it in a CDATA section for consistency
	 */
	protected Element createContent(Document doc, ISnippetItem item) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.CONTENT);
		String contents = item.getContentString();
		if (contents != null && contents.length() > 0) {
			/*
			 * EOL translation
			 * (https://bugs.eclipse.org/bugs/show_bug.cgi?id=102941).
			 * Normalize to '\n'.
			 */
			contents = StringUtils.replace(contents, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			contents = StringUtils.replace(contents, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			element.appendChild(doc.createCDATASection(contents));
		}
		return element;
	}

	/**
	 * Create and save the content property of a ISnippetItem - always place
	 * it in a CDATA section for consistency
	 */
	protected Element createDescription(Document doc, String description) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.DESCRIPTION);
		if (description != null && description.length() > 0)
			element.appendChild(doc.createCDATASection(description));
		return element;
	}

	protected Document createDocument(SnippetDefinitions defs) {
		Document document = CommonXML.getDocumentBuilder().getDOMImplementation().createDocument(null, SnippetsPlugin.NAMES.SNIPPETS, null);
		Element root = document.getDocumentElement();
		for (int i = 0; i < defs.getCategories().size(); i++) {
			ISnippetCategory category = (ISnippetCategory) defs.getCategories().get(i);
			Element categoryElement = createCategory(document, category);
			root.appendChild(categoryElement);
		}
		return document;
	}

	/**
	 * Create and save the properties known for LibraryItems
	 */
	protected Element createItem(Document doc, ISnippetItem item) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.ITEM);
		assignEntryProperties(item, element);
		assignSourceFor(item, element);
		element.setAttribute(SnippetsPlugin.NAMES.CATEGORY, ((SnippetPaletteDrawer) item.getCategory()).getId());
		if (((SnippetPaletteItem) item).getClassName() != null)
			element.setAttribute(SnippetsPlugin.NAMES.CLASSNAME, ((SnippetPaletteItem) item).getClassName());
		if (((SnippetPaletteItem) item).getEditorClassName() != null)
			element.setAttribute(SnippetsPlugin.NAMES.EDITORCLASSNAME, ((SnippetPaletteItem) item).getEditorClassName());
		element.appendChild(createContent(doc, item));
		ISnippetVariable[] variables = item.getVariables();
		for (int i = 0; i < variables.length; i++) {
			Element variable = createVariable(doc, variables[i]);
			element.appendChild(variable);
		}
		if (Logger.DEBUG_DEFINITION_PERSISTENCE)
			System.out.println("User item writer saving item " + ((SnippetPaletteDrawer) item.getCategory()).getId() + ":" + ((SnippetPaletteItem) item).getId()); //$NON-NLS-1$ //$NON-NLS-2$
		return element;
	}

	/**
	 * Save the list of plugins already seen as there may no longer be
	 * references to them in the remaining categories and items
	 */
	protected Element createPluginRecord(Document doc, PluginRecord record) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.PLUGIN);
		element.setAttribute(SnippetsPlugin.NAMES.NAME, record.getPluginName());
		element.setAttribute(SnippetsPlugin.NAMES.VERSION, record.getPluginVersion());
		if (Logger.DEBUG_DEFINITION_PERSISTENCE)
			System.out.println("User item writer saving plugin record " + record.getPluginName() + "/" + record.getPluginVersion()); //$NON-NLS-1$ //$NON-NLS-2$
		return element;
	}

	/**
	 * Create and save the values for a ISnippetVariable
	 */
	protected Element createVariable(Document doc, ISnippetVariable variable) {
		Element element = doc.createElement(SnippetsPlugin.NAMES.VARIABLE);
		element.setAttribute(SnippetsPlugin.NAMES.ID, ((SnippetVariable) variable).getId());
		if (variable.getName() != null)
			element.setAttribute(SnippetsPlugin.NAMES.NAME, variable.getName());
		if (variable.getDefaultValue() != null)
			element.setAttribute(SnippetsPlugin.NAMES.DEFAULT, variable.getDefaultValue());
		element.appendChild(createDescription(doc, variable.getDescription()));
		return element;
	}

	protected String getFilename() {
		String name = null;
		try {
			Bundle bundle = Platform.getBundle(SnippetsPlugin.BUNDLE_ID);
			name = Platform.getStateLocation(bundle).toString() + "/user.xml"; //$NON-NLS-1$
		}
		catch (Exception e) {
			name = "/user.xml"; //$NON-NLS-1$
		}
		return name;
	}

	public String toXML(ISnippetsEntry entry) {
		Document document = CommonXML.getDocumentBuilder().getDOMImplementation().createDocument(null, SnippetsPlugin.NAMES.SNIPPETS, null);
		ByteArrayOutputStream output = new ByteArrayOutputStream();

		if (entry instanceof ISnippetItem) {
			ISnippetItem item = (ISnippetItem) entry;
			Element itemElement = createItem(document, item);
			document.getDocumentElement().appendChild(itemElement);
		}
		else {
			ISnippetCategory category = (ISnippetCategory) entry;
			Element categoryElement = createCategory(document, category);
			document.getDocumentElement().appendChild(categoryElement);
		}

		try {
			CommonXML.serialize(document, output);
		}
		catch (IOException e) {
			return e.getMessage();
		}
		String retVal = null;
		try {
			retVal = new String(output.toByteArray(), "utf16"); //$NON-NLS-1$
		}
		catch (UnsupportedEncodingException e1) {
			retVal = new String(output.toByteArray());
		}
		return retVal;
	}

	public void write(SnippetDefinitions definitions) {
		try {
			FileOutputStream ostream = new FileOutputStream(getFilename());
			write(definitions, ostream);
		}
		catch (IOException e) {
			Logger.logException("could not save " + getFilename(), e); //$NON-NLS-1$
		}
	}

	public void write(SnippetDefinitions definitions, OutputStream stream) {
		Document document = createDocument(definitions);
		try {
			CommonXML.serialize(document, stream);
			stream.flush();
		}
		catch (IOException e) {
			Logger.log(Logger.ERROR, "could not save " + stream, e); //$NON-NLS-1$
		}
		finally {
			try {
				stream.close();
				document = null;
			}
			catch (IOException e) {
				// nothing to be done while closing
			}
		}
	}

}