/*******************************************************************************
 * Copyright (c) 2014 Christian Pontesegger and others.
 * 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/
 *
 * SPDX-License_Identifier: EPL-2.0
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/
package org.eclipse.ease;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.ease.sign.ISignatureConstants;
import org.eclipse.ease.sign.ScriptSignatureException;
import org.eclipse.ease.sign.SignatureInfo;

public abstract class AbstractCodeParser implements ICodeParser {

	public static final Pattern PARAMETER_PATTERN = Pattern.compile("[^\\p{Alnum}-_]*?\\s*([\\p{Alnum}-_]+)\\s*:(.*)");

	public static Map<String, String> extractKeywords(String comment) {
		final Map<String, String> keywords = new HashMap<>();

		if (comment != null) {
			String key = null;
			for (String line : comment.split("\\r?\\n")) {
				final Matcher matcher = PARAMETER_PATTERN.matcher(line);
				if (matcher.matches()) {
					// key value pair found
					key = matcher.group(1);
					keywords.put(key, matcher.group(2).trim());

				} else if (key != null) {
					if (!line.trim().isEmpty()) {
						// check that we do not have a delimiter line (all same chars)
						line = line.trim();
						if (!Pattern.matches("[" + line.charAt(0) + "]+", line))
							// line belongs to previous key value pair
							keywords.put(key, keywords.get(key) + " " + line.trim());
						else
							// line does not belong to previous key anymore
							key = null;
					} else
						// remove cached key as we hit an empty line
						key = null;
				}

				// any other line will be ignored
			}
		}

		return keywords;
	}

	/**
	 * Default implementation to extract the first comment area from a stream. Looks for block and line comments. Might be replaced by more specific
	 * implementations for dedicated languages.
	 *
	 * @param stream
	 *            code content stream
	 * @return comment data without decoration characters (eg: '*' at beginning of each line)
	 */
	@Override
	public String getHeaderComment(final InputStream stream) {
		final StringBuilder comment = new StringBuilder();

		final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));

		boolean isComment = true;
		boolean isBlock = false;
		try {
			do {
				String line = reader.readLine();
				if (line == null)
					break;

				line = line.trim();

				if (isBlock) {
					if (line.contains(getBlockCommentEndToken())) {
						isBlock = false;
						line = line.substring(0, line.indexOf(getBlockCommentEndToken()));
					}

					comment.append(stripCommentLine(line.trim())).append('\n');
					continue;

				} else if ((hasBlockComment()) && (line.startsWith(getBlockCommentStartToken()))) {
					isBlock = true;
					line = line.substring(getBlockCommentStartToken().length()).trim();
					comment.append(stripCommentLine(line)).append('\n');
					continue;

				} else if (line.startsWith(getLineCommentToken())) {
					comment.append(stripCommentLine(line.substring(getLineCommentToken().length()).trim())).append('\n');
					continue;
				}

				if (line.isEmpty())
					continue;

				// not a comment line, not empty
				if (!isAcceptedBeforeHeader(line))
					isComment = false;

			} while (isComment);

		} catch (final IOException e) {
			Logger.error(Activator.PLUGIN_ID, "Could not parse input stream header", e);
			return "";
		}

		return comment.toString();
	}

	/**
	 * Allows to remove special delimiter characters from a comment line. Typically comments might start with a character like '*' or '#' depending on the
	 * script language.
	 *
	 * @param commentLine
	 *            single comment line
	 * @return modified comment line
	 */
	protected String stripCommentLine(String commentLine) {
		return commentLine;
	}

	@Override
	public boolean isAcceptedBeforeHeader(String line) {
		return false;
	}

	@Override
	public SignatureInfo getSignatureInfo(final InputStream stream) throws ScriptSignatureException {
		final BufferedReader bReader = new BufferedReader(new InputStreamReader(stream));
		try {
			String prev, cur;

			// contentBuffer is used to get content excluding signature block. It is updated continuously because in rare cases, we may come to know that
			// what we have read yet is not an actual signature block but part of original script.
			final StringBuffer contentBuffer = new StringBuffer();

			cur = bReader.readLine();
			if (cur == null)
				return null;

			// A line before BEGIN_STRING will be comment and to not include that in contentOnly, prev is used. Using prev, contentOnly will be appended with
			// previous line only if next line is not BEGIN_STRING.
			prev = cur;
			while ((cur = bReader.readLine()) != null) {

				while (!cur.equals(ISignatureConstants.BEGIN_STRING)) {
					contentBuffer.append(prev + "\n");
					prev = cur;
					cur = bReader.readLine();
					if (cur == null)
						return null;
				}

				final StringBuffer contentOnlyBuffer = new StringBuffer(contentBuffer);
				// remove an extra \n character at end. Since this content is used for verification. Same script is required in contentOnly as it was before
				// signing
				if (contentOnlyBuffer.length() > 0)
					contentOnlyBuffer.deleteCharAt(contentOnlyBuffer.length() - 1);

				contentBuffer.append(prev + "\n");
				if (!prev.equals(getBlockCommentStartToken())) {
					// if start block comment is not present, it is not a signature block
					prev = cur;
					continue;
				}

				contentBuffer.append(cur + "\n");

				// else{ continue; } denote that signature in proper format is not yet found and can be found later. So, continue with finding BEGIN_STRING.
				// else{ break; } denote that end of script is reached and so, return null.

				// hash param tag
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(ISignatureConstants.HASH_PARAM_TAG)) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// hash value
				String messageDigestAlgo;
				cur = bReader.readLine();
				if (cur != null) {
					messageDigestAlgo = cur;
					contentBuffer.append(cur + "\n");
				} else
					break;

				// new line
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.isEmpty()) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// provider param tag
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(ISignatureConstants.PROVIDER_PARAM_TAG)) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// provider value
				String provider;
				cur = bReader.readLine();
				if (cur != null) {
					provider = cur;
					contentBuffer.append(cur + "\n");
				} else
					break;

				// following block checks for empty line. If one is not found, then restart checking BEGIN_STRING
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.isEmpty()) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// signature tag
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(ISignatureConstants.SIGNATURE_TAG)) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// following block fetches signature
				final StringBuffer signBuf = new StringBuffer();
				while (((cur = bReader.readLine()) != null) && !cur.isEmpty()) {
					signBuf.append(cur);
					contentBuffer.append(cur + "\n");
				}

				if (cur == null)
					break;

				contentBuffer.append(cur + "\n");

				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(ISignatureConstants.CERTIFICATE_TAG)) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// following block fetches certificates separated by colon(:)
				final StringBuffer certBuf = new StringBuffer();
				while (((cur = bReader.readLine()) != null) && !cur.isEmpty()) {
					certBuf.append(cur);
					contentBuffer.append(cur + "\n");
				}

				if (cur == null)
					break;

				contentBuffer.append(cur + "\n");

				// end string
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(ISignatureConstants.END_STRING)) {
						prev = cur;
						continue;
					}
					contentBuffer.append(cur + "\n");
				} else
					break;

				// end comment token
				cur = bReader.readLine();
				if (cur != null) {
					if (!cur.equals(getBlockCommentEndToken())) {
						// if end block comment is not present, it is not a signature block
						prev = cur;
						continue;
					}

					contentBuffer.append(cur + "\n");
				} else
					break;

				// checks end of script
				cur = bReader.readLine();
				if (cur != null)
					throw new ScriptSignatureException("Text after signature is not allowed");
				else {
					final String signature = signBuf.toString();
					final String certificates[] = certBuf.toString().split(":");
					return new SignatureInfo(signature, provider, messageDigestAlgo, certificates, contentOnlyBuffer.toString());
				}
			}
			return null;

		} catch (final IOException e) {
			Logger.error(Activator.PLUGIN_ID, "An IO error occurred while reading file.", e);
			throw new ScriptSignatureException("An IO error occurred while reading file.", e);

		} finally {
			try {
				if (bReader != null)
					bReader.close();
			} catch (final IOException e) {
				Logger.error(Activator.PLUGIN_ID, "File already closed.", e);
			}
		}

	}

	protected abstract boolean hasBlockComment();

	protected abstract String getBlockCommentEndToken();

	protected abstract String getBlockCommentStartToken();

	protected abstract String getLineCommentToken();
}
