/*******************************************************************************
 * Copyright (c) 2017-2019 Aston University
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License, v. 2.0 are satisfied: GNU General Public License, version 3.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-3.0
 *
 * Contributors:
 *     Orjuwan Al-Wadeai - Test For ConfigFileParser
 *     Antonio Garcia-Dominguez - Use a temporary file
 ******************************************************************************/

package org.eclipse.hawk.service.servlet.config;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.eclipse.hawk.service.servlet.config.ConfigFileParser;
import org.eclipse.hawk.service.servlet.config.HawkInstanceConfig;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import com.google.common.io.Files;

public class ConfigFileParserTest {
	private static final String SERVERCONFIG_PATH = "resources/ServerConfig/";
	private static final String XML_PATH = SERVERCONFIG_PATH + "instance_3.xml";

	@Rule
	public TemporaryFolder folder = new TemporaryFolder();

	private ConfigFileParser parser;
	private HawkInstanceConfig config;
	private File fConfig;

	@Before
	public void setup() throws IOException {
		File fOriginal = new File(XML_PATH);
		fConfig = folder.newFile(fOriginal.getName());
		Files.copy(fOriginal, fConfig);
	}

	@Test
	public void testParseFile() {
		parseXml();

		// config values
		assertEquals("Instance Name:", "instance_3", config.getName());
		assertEquals("Instance Backend:", "org.eclipse.hawk.orientdb.OrientDatabase", config.getBackend());
		assertEquals("Instance Delay Max:", 512000, config.getDelayMax());
		assertEquals("Instance Delay Min:", 5000, config.getDelayMin());

		final List<String> plugins = config.getPlugins();
		assertEquals("Instance Number of Plugins:", 8, plugins.size());
		assertTrue(plugins.contains("org.eclipse.hawk.emf.metamodel.EMFMetaModelResourceFactory"));
		assertTrue(plugins.contains("org.eclipse.hawk.emf.model.EMFModelResourceFactory"));
		assertTrue(plugins.contains("org.eclipse.hawk.graph.syncValidationListener.SyncValidationListener"));
		assertTrue(plugins.contains("org.eclipse.hawk.graph.updater.GraphModelUpdater"));
		assertTrue(plugins.contains("org.eclipse.hawk.modelio.exml.listeners.ModelioGraphChangeListener"));
		assertTrue(plugins.contains("org.eclipse.hawk.modelio.exml.metamodel.ModelioMetaModelResourceFactory"));
		assertTrue(plugins.contains("org.eclipse.hawk.modelio.exml.model.ModelioModelResourceFactory"));
		assertTrue(plugins.contains("org.eclipse.hawk.epsilon.emc.EOLQueryEngine"));

		assertEquals("Instance Number of Metamodels:", 1, config.getMetamodels().size());
		assertEquals("C:/resources/metamodel/metamodel_descriptor.xml", config.getMetamodels().get(0).getLocation());
		assertEquals("", config.getMetamodels().get(0).getUri());

		assertEquals("Instance Number of Derived Attributes:", 1, config.getDerivedAttributes().size());
		assertEquals("modelio://Modeliosoft.Standard/2.0.00", config.getDerivedAttributes().get(0).getMetamodelUri());
		assertEquals("Class", config.getDerivedAttributes().get(0).getTypeName());
		assertEquals("ownedOperationCount", config.getDerivedAttributes().get(0).getAttributeName());
		assertEquals("Integer", config.getDerivedAttributes().get(0).getAttributeType());

		assertEquals(false, config.getDerivedAttributes().get(0).isMany());
		assertEquals(false, config.getDerivedAttributes().get(0).isOrdered());
		assertEquals(false, config.getDerivedAttributes().get(0).isUnique());

		assertEquals("EOLQueryEngine", config.getDerivedAttributes().get(0).getDerivationLanguage());
		assertEquals("return self.OwnedOperation.size;", config.getDerivedAttributes().get(0).getDerivationLogic().trim());

		assertEquals("Instance Number of Indexed Attributes:", 1, config.getIndexedAttributes().size());
		assertEquals("modelio://Modeliosoft.Standard/2.0.00", config.getIndexedAttributes().get(0).getMetamodelUri());
		assertEquals("Class", config.getIndexedAttributes().get(0).getTypeName());
		assertEquals("Name", config.getIndexedAttributes().get(0).getAttributeName());

		assertEquals("Instance Number of :Repositories", 1, config.getRepositories().size());
		assertEquals("file:///C:/Desktop/Hawk/Zoo/", config.getRepositories().get(0).getLocation());
		assertEquals("org.eclipse.hawk.localfolder.LocalFolder", config.getRepositories().get(0).getType());
		assertNull(config.getRepositories().get(0).getUser());
		assertNull(config.getRepositories().get(0).getPass());
		assertEquals(false, config.getRepositories().get(0).isFrozen());
	}

	private void parseXml() {
		parser = new ConfigFileParser();
		config = parser.parse(fConfig);
	}

	@Test
	public void testSaveConfigToFile() {
		parseXml();
		parser.saveConfigAsXml(config);
		testParseFile();
	}

}
