/********************************************************************************
 * Copyright (c) 2015-2018 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;

import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_ID;
import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_SOURCENAME;
import static org.eclipse.mdm.businessobjects.service.EntityService.V;

import java.util.Map;
import java.util.NoSuchElementException;

import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.dflt.model.Classification;
import org.eclipse.mdm.api.dflt.model.Domain;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.ProjectDomain;
import org.eclipse.mdm.api.dflt.model.TemplateTest;
import org.eclipse.mdm.api.dflt.model.ValueList;
import org.eclipse.mdm.businessobjects.control.FileLinkActivity;
import org.eclipse.mdm.businessobjects.entity.ContextResponse;
import org.eclipse.mdm.businessobjects.entity.I18NResponse;
import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
import org.eclipse.mdm.businessobjects.entity.SearchAttributeResponse;
import org.eclipse.mdm.businessobjects.service.ContextService;
import org.eclipse.mdm.businessobjects.service.EntityFileLink;
import org.eclipse.mdm.businessobjects.service.EntityService;
import org.eclipse.mdm.businessobjects.utils.RequestBody;
import org.eclipse.mdm.businessobjects.utils.ServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.vavr.Value;
import io.vavr.collection.List;
import io.vavr.collection.Seq;
import io.vavr.collection.Vector;
import io.vavr.control.Try;

/**
 * {@link Test} resource
 * 
 * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
 *
 */
@Tag(name = "Test")
@Path("/environments/{" + REQUESTPARAM_SOURCENAME + "}/tests")
public class TestResource {

	private static final String ATTR_WITHTESTSTEPS = "WithTestSteps";

	private static final Logger LOG = LoggerFactory.getLogger(TestResource.class);

	@EJB
	private TestService testService;

	@EJB
	private EntityService entityService;

	@EJB
	private ContextService contextService;

	@EJB
	private FileLinkActivity fileLinkActivity;

	/**
	 * delegates the request to the {@link TestService}
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param filter     filter string to filter the {@link Test} result
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Operation(summary = "Find Tests by filter", description = "Get list of Tests", responses = {
			@ApiResponse(description = "The projects", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	public Response getTests(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "Filter expression", required = false) @QueryParam("filter") String filter) {

		return Try.of(() -> testService.getTests(sourceName, filter)).map(List::ofAll)
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK, Test.class))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * delegates the request to the {@link TestService}
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Operation(summary = "Get the search attributes", description = "Get a list of search attributes", responses = {
			@ApiResponse(description = "The search attributes", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/searchattributes")
	public Response getSearchAttributes(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {

		return Try.of(() -> testService.getSearchAttributes(sourceName))
				.map(attrs -> ServiceUtils.toResponse(new SearchAttributeResponse(attrs), Status.OK))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * delegates the request to the {@link TestService}
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         id of the {@link Test}
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Operation(summary = "Find a Test by ID", description = "Returns Test based on ID", responses = {
			@ApiResponse(description = "The Test", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}")
	public Response findTest(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the Test", required = true) @PathParam(REQUESTPARAM_ID) String id) {
		return entityService.find(V(sourceName), Test.class, V(id))
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * delegates the request to the {@link TestService}
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Operation(summary = "Get the Test localizations", description = "Returns Test localizations", responses = {
			@ApiResponse(description = "The Test localizations", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/localizations")
	public Response localize(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {

		try {
			Map<Attribute, String> localizedAttributeMap = this.testService.localizeAttributes(sourceName);
			Map<EntityType, String> localizedEntityTypeMap = this.testService.localizeType(sourceName);
			return ServiceUtils.toResponse(new I18NResponse(localizedEntityTypeMap, localizedAttributeMap), Status.OK);

		} catch (RuntimeException e) {
			LOG.error(e.getMessage(), e);
			throw new WebApplicationException(e.getMessage(), e, Status.INTERNAL_SERVER_ERROR);
		}
	}

	/**
	 * Returns the created {@link Test}.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param body       The {@link Test} to create.
	 * @return the created {@link Test} as {@link Response}.
	 */
	@POST
	@Operation(summary = "Create a new Test", responses = {
			@ApiResponse(description = "The created Test", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	public Response create(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			String body) {
		// TODO

		Seq<Value<?>> extractRequestBody = entityService.extractRequestBody(body, sourceName,
				io.vavr.collection.List.of(Pool.class, org.eclipse.mdm.api.dflt.model.Status.class, TemplateTest.class,
						ProjectDomain.class, Domain.class, Classification.class));

		java.util.List<Value<?>> asJavaMutable = extractRequestBody.asJavaMutable();

		org.eclipse.mdm.api.dflt.model.Status status = null;
		ProjectDomain projectDomain = null;
		Domain domain = null;

		Seq<Value<?>> finalAttrSeq = Vector.empty();

		for (Value<?> v : asJavaMutable) {
			if (v.get() instanceof org.eclipse.mdm.api.dflt.model.Status) {
				status = (org.eclipse.mdm.api.dflt.model.Status) v.get();
				extractRequestBody.remove(v);
			} else if (v.get() instanceof ProjectDomain) {
				projectDomain = (ProjectDomain) v.get();
				extractRequestBody.remove(v);
			} else if (v.get() instanceof Domain) {
				domain = (Domain) v.get();
				extractRequestBody.remove(v);
			} else {
				finalAttrSeq = finalAttrSeq.append(v);
			}
		}

		if (status != null && projectDomain != null && domain != null) {
			Classification classification = testService.getClassification(sourceName, status, projectDomain, domain);
			finalAttrSeq = finalAttrSeq.append(V(classification));
		}

		RequestBody requestBody = RequestBody.create(body);

		try {
			Try<String> stringValueSupplier = requestBody.getStringValueSupplier(ATTR_WITHTESTSTEPS);
			finalAttrSeq = finalAttrSeq.append(V(Boolean.valueOf(stringValueSupplier.get())));
		} catch (NoSuchElementException e) {
			// If with TestStep not exist, do nothing
		}

		return entityService.create(V(sourceName), Test.class, finalAttrSeq)
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * Updates the {@link Test} with all parameters set in the given JSON body of
	 * the request.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         the identifier of the {@link TestValue} to update.
	 * @param body       the body of the request containing the attributes to update
	 * @return the updated {@link Test}
	 */
	@PUT
	@Operation(summary = "Update an existing Test", description = "Updates the Test with all parameters set in the body of the request.", responses = {
			@ApiResponse(description = "The updated TestStep", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}")
	@RolesAllowed({ "write-user" })
	public Response update(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the Test", required = true) @PathParam(REQUESTPARAM_ID) String id,
			String body) {
		RequestBody requestBody = RequestBody.create(body);

		return entityService
				.update(V(sourceName), entityService.find(V(sourceName), Test.class, V(id)),
						requestBody.getValueMapSupplier())
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * Deletes and returns the deleted {@link Test}.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         The identifier of the {@link Test} to delete.
	 * @return the deleted {@link ValueList }s as {@link Response}
	 */
	@DELETE
	@Operation(summary = "Delete an existing Test", responses = {
			@ApiResponse(description = "The deleted Test", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}")
	public Response delete(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the Test", required = true) @PathParam(REQUESTPARAM_ID) String id) {
		return entityService.delete(V(sourceName), entityService.find(V(sourceName), Test.class, V(id)))
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * Stream the contents of a file link.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         The identifier of the {@link Test} which contains the
	 *                   {@link FileLink}
	 * @param remotePath The remote path of the {@link FileLink} to identify, which
	 *                   {@link FileLink}'s content is requests.
	 * @return The content of the file as {@link javax.ws.rs.core.StreamingOutput}.
	 *         The response also has the MimeType set according to
	 *         {@link FileLink#getMimeType()}.
	 */
	@GET
	@Operation(summary = "Stream the contents of a file link", responses = {
			@ApiResponse(description = "The content of the file link as a stream. MimeType is set to that of the file link.", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Invalid ID or remote path supplied") })
	@Path("/{" + REQUESTPARAM_ID + "}/files/{remotePath}")
	public Response streamFileLink(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the Test containing the file link", required = true) @PathParam(REQUESTPARAM_ID) String id,
			@Parameter(description = "The remote path of the file link whose content is to be retrieved", required = true) @PathParam("remotePath") String remotePath) {

		return entityService.find(V(sourceName), Test.class, V(id)).map(fa -> new EntityFileLink(fa, remotePath))
				.map(efl -> Response.ok(efl.toStreamingOutput(fileLinkActivity, sourceName),
						efl.getFileLink().getMimeType().toString()).build())
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * delegates the request to the {@link TestStepService}
	 *
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         id of the {@link TestStep}
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Operation(summary = "Get the test constant context data for a Test", description = "Returns the test constant context", responses = {
			@ApiResponse(responseCode = "200", description = "The test constant context data", content = @Content(schema = @Schema(implementation = ContextResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts")
	public Response findContext(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id) {
		return contextService.getTestContext(V(sourceName), V(id), false).map(ServiceUtils::contextMapToJava)
				.map(ContextResponse::new).map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * Updates the context of {@link TestStep} with all parameters set in the given
	 * JSON body of the request.
	 *
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         the identifier of the {@link TestStep} to update.
	 * @param body       the body of the request containing the attributes to update
	 * @return the context map of the updated {@link TestStep}
	 */
	@PUT
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts")
	@RolesAllowed({ "write-user" })
	public Response updateContext(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id, String body) {

		return entityService.find(V(sourceName), TestStep.class, V(id))
				.map(testStep -> contextService.updateContext(body, testStep)).map(ContextResponse::new)
				.map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

}
