/********************************************************************************
 * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.businessobjects.boundary.integrationtest;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

import org.junit.Assume;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;

import io.restassured.http.ContentType;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;

/**
 * Abstract test class for Entity resources. Tests are executed in
 * {@code FixMethodOrder(MethodSorters.NAME_ASCENDING)} as {@link test1Create},
 * {@link test2Find()}, {@link test3FindAll()}, {@link test4Update()} and
 * {@link test5Delete()} depend on the entity created by test1Create().
 * 
 * @author Alexander Nehmer, science+computing AG Tuebingen (Atos SE)
 *
 */
// TODO anehmer on 2017-11-23: test for specific return codes
// TODO anehmer on 2017-11-24: expand tests to localization and search attribute
// information
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public abstract class EntityResourceIntegrationTest extends ResourceIntegrationTest {

	private static final Logger LOGGER = LoggerFactory.getLogger(EntityResourceIntegrationTest.class);

	@Test
	public void test1Create() {
		// only execute if not skipped by implementing test class
		Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.CREATE));

		createEntity();
	}

	/**
	 * Static method that can be utilised by tests to create a specific entity or is
	 * called indirectly by JUnit
	 */
	public static void createEntity() {
		// do not create entity if it was already created in a currently running
		// prepareTestData() cascade
		if (isTestDataValuePresent(TESTDATA_ENTITY_ID)) {
			LOGGER.debug(getContextClass().getSimpleName() + ".create() aborted as entity "
					+ getTestDataValue(TESTDATA_ENTITY_NAME) + " of type " + getTestDataValue(TESTDATA_ENTITY_TYPE)
					+ " was already created");
			return;
		}

		LOGGER.debug(getContextClass().getSimpleName() + ".create() sending POST to "
				+ getTestDataValue(TESTDATA_RESOURCE_URI) + " with: " + getTestDataValue(TESTDATA_CREATE_JSON_BODY));

		ExtractableResponse<io.restassured.response.Response> response = given().contentType(ContentType.JSON)
				.body(getTestDataValue(TESTDATA_CREATE_JSON_BODY)).post(getTestDataValue(TESTDATA_RESOURCE_URI)).then()
				.log().ifError().contentType(ContentType.JSON)
				// do not check for name equality as that might be created randomly
				.and().body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract();

		LOGGER.debug(getContextClass().getSimpleName() + " created " + response.asString());

		putTestDataValue(TESTDATA_ENTITY_ID, response.path("data.first().id"));
		putTestDataValue(TESTDATA_ENTITY_NAME, response.path("data.first().name"));
	}

	@Test
	public void test2Find() {
		// only execute if not skipped by implementing test class
		Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.FIND));

		String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/"
				+ (EntityResourceIntegrationTest.findByName.getOrElse(getContextClass(), false)
						? getTestDataValue(TESTDATA_ENTITY_NAME)
						: getTestDataValue(TESTDATA_ENTITY_ID));

		LOGGER.debug(getContextClass().getSimpleName() + ".find() sending GET to " + uri);

		ExtractableResponse<Response> response = given().get(uri).then().log().ifError().contentType(ContentType.JSON)
				.body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME)))
				.body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract();

		LOGGER.debug(getContextClass().getSimpleName() + " found " + response.asString());
	}

	/**
	 * Finds the first entity of the {@code EntityType} set in the context and put
	 * the found ID in the context for further usage
	 */
	public static void findFirst() {
		LOGGER.debug(getContextClass().getSimpleName() + ".find() sending GET to "
				+ getTestDataValue(TESTDATA_RESOURCE_URI));

		String id = given().get(getTestDataValue(TESTDATA_RESOURCE_URI)).then().log().ifError()
				.contentType(ContentType.JSON)
				.body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME)))
				.body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract()
				.path("data.first().id");

		LOGGER.debug(getContextClass().getSimpleName() + " found " + getTestDataValue(TESTDATA_ENTITY_TYPE)
				+ " with ID " + id);

		putTestDataValue(TESTDATA_ENTITY_ID, id);
	}

	@Test
	public void test3FindAll() {
		// only execute if not skipped by implementing test class
		Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.FINDALL));

		LOGGER.debug(getContextClass().getSimpleName() + ".findAll() sending GET to "
				+ getTestDataValue(TESTDATA_RESOURCE_URI));

		ExtractableResponse<Response> response = given().get(getTestDataValue(TESTDATA_RESOURCE_URI)).then().log()
				.ifError().contentType(ContentType.JSON)
				.body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract();

		LOGGER.debug(getContextClass().getSimpleName() + " found all " + response.asString());
	}

	// TODO anehmer on 2017-11-09: test findAll with filter

	// TODO anehmer on 2018-02-06: update of relations are not checked as the
	// returned Json does not include relations
	@Test
	public void test4Update() {
		// only execute if not skipped by implementing test class
		Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.UPDATE));

		updateEntity();
	}

	/**
	 * Static method that can be utilised by tests to update a specific entity or is
	 * called indirectly by JUnit
	 */
	public static void updateEntity() {
		JsonObject json;
		// if no UPDATE_JSON_BODY is defined in implementing test, just run the MimeType
		// update
		if (!isTestDataValuePresent(TESTDATA_UPDATE_JSON_BODY)) {
			json = new JsonObject();
		}
		// or add it to the existing update
		else {
			json = new JsonParser().parse(getTestDataValue(TESTDATA_UPDATE_JSON_BODY)).getAsJsonObject();
		}
		json.add("MimeType", new JsonPrimitive("updatedMimeType"));
		putTestDataValue(TESTDATA_UPDATE_JSON_BODY, json.toString());

		String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" + getTestDataValue(TESTDATA_ENTITY_ID);

		LOGGER.debug(getContextClass().getSimpleName() + ".update() sending PUT to " + uri + " with: "
				+ getTestDataValue(TESTDATA_UPDATE_JSON_BODY));

		ExtractableResponse<Response> response = given().contentType(ContentType.JSON)
				// TODO anehmer on 2017-11-15: the update should use different data but as the
				// returned JSON represents
				// the entity prior update it does not make any difference as the update is
				// performed just based on identical data. We should discuss the PUT-behaviour
				// instead: return the old or updated object as returning the updated one would
				// mean to perform another get as the ODSTransaction.update() does not return
				// the updated entity
				// TODO anehmer on 2017-11-15: use Description to test update
				.body(getTestDataValue(TESTDATA_UPDATE_JSON_BODY)).put(uri).then().log().ifError()
				.contentType(ContentType.JSON)
				.body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME)))
				.body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE)))
				.body("data.first().attributes.find {it.name == 'MimeType'}.value", equalTo("updatedMimeType"))
				.extract();

		LOGGER.debug(getContextClass().getSimpleName() + " updated " + response.asString());
	}

	@Test
	public void test5Delete() {
		// only execute if not skipped by implementing test class
		Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.DELETE));

		deleteEntity();
	}

	/**
	 * Static method that can be utilised by tests to delete a specific entity or is
	 * called indirectly by JUnit
	 */
	public static void deleteEntity() {
		String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" + getTestDataValue(TESTDATA_ENTITY_ID);

		LOGGER.debug(getContextClass().getSimpleName() + ".delete() sending DELETE to " + uri);

		ExtractableResponse<Response> response = given().delete(uri).then().log().ifError()
				.body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME)))
				.body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract();

		LOGGER.debug(getContextClass().getSimpleName() + " deleted " + response.asString());

		removeTestDataValue(TESTDATA_ENTITY_ID);
	}

	/**
	 * Gets the logger
	 * 
	 * @return logger configured to current context class
	 */
	public static Logger getLogger() {
		return LOGGER;
	}
}
