/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.pde.internal.build.tasks;

import java.io.*;
import java.nio.charset.StandardCharsets;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

/** 
 * Internal task.
 * This task aims at replacing the generic ids used into a plugin.xml by another value.
 * @since 3.0
 */
public class PluginVersionReplaceTask extends Task {
	private static final String PLUGIN_START_TAG = "<plugin"; //$NON-NLS-1$
	private static final String FRAGMENT_START_TAG = "<fragment"; //$NON-NLS-1$
	private static final String COMMENT_START_TAG = "<!--"; //$NON-NLS-1$
	private static final String COMMENT_END_TAG = "-->"; //$NON-NLS-1$
	private static final String VERSION = "version";//$NON-NLS-1$
	private static final String BACKSLASH = "\""; //$NON-NLS-1$

	//Path of the file where we are replacing the values
	private String pluginFilePath;
	private boolean plugin = true;
	private String newVersion;

	/**
	 * The location of a fragment.xml or plugin.xml file 
	 * @param path
	 */
	public void setPluginFilePath(String path) {
		pluginFilePath = path;
	}

	/**
	 * Set the new version.
	 * @param qualifier the version that will be set in the manifest file.
	 */
	public void setVersionNumber(String qualifier) {
		newVersion = qualifier;
	}

	/**
	 * Set the type of the file.
	 * @param input 
	 */
	public void setInput(String input) {
		if (input.equalsIgnoreCase("fragment.xml")) //$NON-NLS-1$
			plugin = false;
	}

	@Override
	public void execute() {
		StringBuffer buffer = null;
		try {
			buffer = readFile(new File(pluginFilePath));
		} catch (IOException e) {
			throw new BuildException(e);
		}

		//Find the word plugin or fragment
		int startPlugin = scan(buffer, 0, plugin ? PLUGIN_START_TAG : FRAGMENT_START_TAG);
		int startComment = scan(buffer, 0, COMMENT_START_TAG);
		int endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;

		while (startComment != -1 && startPlugin > startComment && startPlugin < endComment) {
			startPlugin = scan(buffer, endComment, plugin ? PLUGIN_START_TAG : FRAGMENT_START_TAG);
			startComment = scan(buffer, endComment, COMMENT_START_TAG);
			endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
		}

		if (startPlugin == -1)
			return;

		int endPlugin = scan(buffer, startPlugin + 1, ">"); //$NON-NLS-1$

		//Find the version tag in the plugin header
		boolean versionFound = false;
		while (!versionFound) {
			int versionAttr = scan(buffer, startPlugin, VERSION);
			if (versionAttr == -1 || versionAttr > endPlugin)
				return;
			if (!Character.isWhitespace(buffer.charAt(versionAttr - 1))) {
				startPlugin = versionAttr + VERSION.length();
				continue;
			}
			//Verify that the word version found is the actual attribute
			int endVersionWord = versionAttr + VERSION.length();
			while (Character.isWhitespace(buffer.charAt(endVersionWord)) && endVersionWord < endPlugin) {
				endVersionWord++;
			}
			if (endVersionWord > endPlugin) //version has not been found 
				return;

			if (buffer.charAt(endVersionWord) != '=') {
				startPlugin = endVersionWord;
				continue;
			}

			//Version has been found, extract the version id and replace it
			int startVersionId = scan(buffer, versionAttr + 1, BACKSLASH);
			int endVersionId = scan(buffer, startVersionId + 1, BACKSLASH);

			buffer.replace(startVersionId + 1, endVersionId, newVersion);
			versionFound = true;
		}
		try (OutputStreamWriter w = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(pluginFilePath)), StandardCharsets.UTF_8)) {
			w.write(buffer.toString());
		} catch (FileNotFoundException e) {
			// ignore
		} catch (IOException e) {
			throw new BuildException(e);
		}
	}

	private int scan(StringBuffer buf, int start, String targetName) {
		return scan(buf, start, new String[] {targetName});
	}

	private int scan(StringBuffer buf, int start, String[] targets) {
		for (int i = start; i < buf.length(); i++) {
			for (int j = 0; j < targets.length; j++) {
				if (i < buf.length() - targets[j].length()) {
					String match = buf.substring(i, i + targets[j].length());
					if (targets[j].equalsIgnoreCase(match))
						return i;
				}
			}
		}
		return -1;
	}

	private StringBuffer readFile(File targetName) throws IOException {
		InputStreamReader reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(targetName)), StandardCharsets.UTF_8);
		StringBuffer result = new StringBuffer();
		char[] buf = new char[4096];
		int count;
		try {
			count = reader.read(buf, 0, buf.length);
			while (count != -1) {
				result.append(buf, 0, count);
				count = reader.read(buf, 0, buf.length);
			}
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				// ignore exceptions here
			}
		}
		return result;
	}
}
