/*******************************************************************************
 * Copyright (c) 2016, 2021 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.acceleo.tests.utils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.aql.AcceleoUtil;
import org.eclipse.acceleo.aql.evaluation.AcceleoEvaluator;
import org.eclipse.acceleo.aql.evaluation.GenerationResult;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.junit.Test;

/**
 * Tests the evalation of a {@link Module} using {@link AcceleoEvaluator}.
 * 
 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
 */
public abstract class AbstractEvaluationTestSuite extends AbstractLanguageTestSuite {

	/**
	 * Copy buffer size.
	 */
	private static final int BUFFER_SIZE = 8192;

	/**
	 * The {@link Resource}.
	 */
	private final Resource model;

	/**
	 * Constructor.
	 * 
	 * @param testFolder
	 *            the test folder path
	 * @throws IOException
	 *             if the tested template can't be read
	 */
	protected AbstractEvaluationTestSuite(String testFolder) throws IOException {
		super(testFolder);
		final File modelFile = getModelFile(new File(getTestFolderPath()));
		final ResourceSet rs = getResourceSet();
		model = getModel(modelFile, rs);
	}

	/**
	 * Gets the {@link Resource}.
	 * 
	 * @param modelFile
	 *            the model {@link File}
	 * @param rs
	 *            the {@link ResourceSet}
	 * @return the {@link Resource}
	 */
	protected Resource getModel(File modelFile, ResourceSet rs) {
		final Resource res;

		final URI modelURI = URI.createFileURI(modelFile.getAbsolutePath());
		if (URIConverter.INSTANCE.exists(modelURI, null)) {
			res = rs.getResource(modelURI, true);
		} else {
			res = null;
		}

		return res;
	}

	/**
	 * Tests the generation by comparing the result of the generation.
	 * 
	 * @throws IOException
	 *             if a file can't be read or written
	 */
	@Test
	public void evaluation() throws IOException {
		final Module module = astResult.getModule();
		final URI generatedFolderURI = URI.createURI("generated/").resolve(model.getURI());
		final List<URI> expectedGeneratedFiles = getExpectedGeneratedFiles(generatedFolderURI);
		final List<URI> unexpectedGeneratedFiles = new ArrayList<URI>();
		AcceleoUtil.generate(evaluator, queryEnvironment, module, model, memoryDestination);

		assertGenerationMessages(evaluator.getGenerationResult());

		// assert generated content
		final GenerationResult result = evaluator.getGenerationResult();
		for (URI memoryGeneratedURI : result.getGeneratedFiles()) {
			final URI generatedURI = URI.createURI(memoryGeneratedURI.toString().substring(
					memoryDestinationString.length())).resolve(generatedFolderURI);
			final URI expectedURI = URI.createURI(generatedURI.toString() + "-expected.txt");
			expectedGeneratedFiles.remove(expectedURI);
			final URI actualURI = URI.createURI(generatedURI.toString() + "-actual.txt");
			if (URIConverter.INSTANCE.exists(expectedURI, null)) {
				final String expectedContent;
				try (InputStream expectedStream = URIConverter.INSTANCE.createInputStream(expectedURI)) {
					expectedContent = getContent(expectedStream, UTF_8); // TODO test other encoding
				}
				final String actualContent;
				try (InputStream actualStream = URIConverter.INSTANCE.createInputStream(memoryGeneratedURI)) {
					actualContent = getContent(actualStream, UTF_8); // TODO test other encoding
				}
				assertEquals(expectedContent, actualContent);
			} else {
				copy(memoryGeneratedURI, actualURI);
				unexpectedGeneratedFiles.add(actualURI);
			}
		}

		if (!unexpectedGeneratedFiles.isEmpty()) {
			fail("unexpected generated file: " + Arrays.deepToString(unexpectedGeneratedFiles.toArray()));
		}
		if (!expectedGeneratedFiles.isEmpty()) {
			fail("expected generated file are missing: " + Arrays.deepToString(expectedGeneratedFiles.toArray(
					new URI[expectedGeneratedFiles.size()])));
		}
	}

	private List<URI> getExpectedGeneratedFiles(URI generatedFolderURI) {
		final List<URI> res = new ArrayList<URI>();

		final File generatedFolder = new File(generatedFolderURI.toFileString());

		final String[] expectedFileNames = generatedFolder.list(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith("-expected.txt");
			}
		});

		if (expectedFileNames != null) {
			for (String expectedFileName : expectedFileNames) {
				res.add(URI.createURI(expectedFileName).resolve(generatedFolderURI));
			}
		}

		return res;
	}

	/**
	 * Asserts the runtime messages.
	 * 
	 * @param generationResult
	 *            the {@link GenerationResult}
	 * @throws IOException
	 */
	private void assertGenerationMessages(GenerationResult generationResult) throws IOException {
		final String actualContent = getRuntimeMessages(generationResult.getDiagnostic());

		final File expectedFile = getExpectedRuntimeMessageFile(new File(getTestFolderPath()));
		final File actualFile = getActualRuntimeMessageFile(new File(getTestFolderPath()));

		if (!expectedFile.exists()) {
			if (!actualFile.exists() && !expectedFile.exists()) {
				actualFile.createNewFile();
			}
			try (FileOutputStream stream = new FileOutputStream(actualFile);) {
				setContent(stream, UTF_8, actualContent);
			}
			fail("file doesn't exist.");
		} else {
			String expectedContent = "";
			try (FileInputStream stream = new FileInputStream(expectedFile);) {
				expectedContent = getContent(stream, UTF_8);
			}
			assertEquals(expectedContent, actualContent);
		}
	}

	/**
	 * Gets the {@link String} representation of the given {@link Diagnostic}.
	 * 
	 * @param diagnostic
	 *            the {@link Diagnostic}
	 * @return the {@link String} representation of the given {@link Diagnostic}
	 */
	private String getRuntimeMessages(Diagnostic diagnostic) {
		final StringBuilder builder = new StringBuilder();

		walkDiagnostic(builder, "", diagnostic);

		return getPortableString(builder.toString());
	}

	private void walkDiagnostic(StringBuilder builder, String prefix, Diagnostic diagnostic) {
		builder.append(prefix + " (" + diagnostic.getSource() + " " + diagnostic.getCode() + " " + diagnostic
				.getSeverity() + ") " + diagnostic.getMessage() + "[" + getDataString(diagnostic.getData())
				+ "]\n");
		for (Diagnostic child : diagnostic.getChildren()) {
			walkDiagnostic(builder, prefix + "  ", child);
		}
	}

	/**
	 * Gets the {@link Diagnostic} data {@link String}.
	 * 
	 * @param data
	 *            the {@link List} of data
	 * @return the {@link Diagnostic} data {@link String}
	 */
	@SuppressWarnings("unchecked")
	private String getDataString(List<?> data) {
		final StringBuilder builder = new StringBuilder();

		if (data != null) {
			for (Object datum : data) {
				if (datum instanceof Map) {
					builder.append("[");
					for (Entry<Object, Object> entry : ((Map<Object, Object>)datum).entrySet()) {
						builder.append("(" + entry.getKey() + ", " + entry.getValue() + "), ");
					}
					builder.append("]");
				} else if (datum != null) {
					builder.append(datum.toString());
				} else {
					builder.append("null");
				}
			}
		}

		return builder.toString();
	}

	/**
	 * Gets the portable version of the given {@link String}.
	 * 
	 * @param textContent
	 *            the text content
	 * @return the portable version of the given {@link String}
	 */
	private String getPortableString(String textContent) {
		String res;

		res = textContent.replaceAll("/home/.*/M2Doc", "/home/.../M2Doc"); // remove folder prefix
		res = res.replaceAll("file:/.*/M2Doc", "file:/.../M2Doc"); // remove folder prefix
		res = res.replaceAll("Aucun fichier ou dossier de ce type", "No such file or directory"); // replace
																									// localized
																									// message
		res = res.replaceAll("20[^ ]* [^ ]* - Lost", "20...date and time... - Lost"); // strip lost user doc
																						// date
		res = res.replaceAll("@[a-f0-9]{5,8}[, )]", "@00000000 "); // object address in toString()
		res = res.replaceAll(
				"(\\tat [a-zA-Z0-9$./]+((<|&lt;)init(>|&gt;))?\\((Unknown Source|Native Method|[a-zA-Z0-9$./]+java:[0-9]+)\\)\n?)+",
				"...STACK..."); // strip stack traces
		res = res.replaceAll("127.0.0.100:12.345", "127.0.0.100:12 345"); // localized port...
		res = res.replaceAll("127.0.0.100:12,345", "127.0.0.100:12 345"); // localized port...

		return res;
	}

	/**
	 * Copies all bytes from a source {@link URI} to a destination {@link URI}.
	 * 
	 * @param sourceURI
	 *            the source {@link URI}
	 * @param destURI
	 *            the destination {@link URI}
	 * @return the number of copied bytes
	 * @throws IOException
	 *             if the copy can't be done
	 */
	private static long copy(URI sourceURI, URI destURI) throws IOException {
		try (InputStream source = URIConverter.INSTANCE.createInputStream(sourceURI);
				OutputStream dest = URIConverter.INSTANCE.createOutputStream(destURI);) {
			long nread = 0L;
			byte[] buf = new byte[BUFFER_SIZE];
			int n;
			while ((n = source.read(buf)) > 0) {
				dest.write(buf, 0, n);
				nread += n;
			}
			return nread;
		}
	}

}
