/********************************************************************************
 * Copyright (c) 2015-2020 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_ATTRIBUTENAME;
import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_CONTEXTCOMPONENTNAME;
import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_CONTEXTTYPE;
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 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.container.ResourceContext;
import javax.ws.rs.core.Context;
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.model.ContextType;
import org.eclipse.mdm.api.base.model.Environment;
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.TemplateTestStep;
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.ContextSensorResponse;
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.EntityService;
import org.eclipse.mdm.businessobjects.utils.RequestBody;
import org.eclipse.mdm.businessobjects.utils.ServiceUtils;

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.collection.List;
import io.vavr.control.Try;

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

	@EJB
	private TestStepService testStepService;

	@EJB
	private EntityService entityService;

	@EJB
	private ContextService contextService;

	@EJB
	private FileLinkActivity fileLinkActivity;

	@Context
	private ResourceContext resourceContext;

	/**
	 * delegates the request to the {@link TestStepService}
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param filter     filter string to filter the TestStep result
	 * @return the result of the delegated request as {@link Response}
	 */
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Operation(summary = "Find TestSteps by filter", description = "Get list of TestSteps", responses = {
			@ApiResponse(description = "The projects", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Error") })
	public Response getTestSteps(
			@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(() -> testStepService.getTestSteps(sourceName, filter)).map(List::ofAll)
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK, TestStep.class)).get();

	}

	/**
	 * delegates the request to the {@link TestStepService}
	 * 
	 * @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(() -> testStepService.getSearchAttributes(sourceName))
				.map(attrs -> ServiceUtils.toResponse(new SearchAttributeResponse(attrs), Status.OK)).get();
	}

	/**
	 * 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 = "Find a TestStep by ID", description = "Returns TestStep based on ID", responses = {
			@ApiResponse(description = "The TestStep", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}")
	public Response findTestStep(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the TestStep", required = true) @PathParam(REQUESTPARAM_ID) String id) {
		return entityService.find(V(sourceName), TestStep.class, V(id))
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).get();
	}

	/**
	 * 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 complete context data for a TestStep", description = "Returns the complete context", responses = {
			@ApiResponse(responseCode = "200", description = "The TestStep 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(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@Parameter(description = "ID of the TestStep", required = true) @PathParam(REQUESTPARAM_ID) String id) {
		return contextService.getTestStepContext(V(sourceName), V(id)).map(ServiceUtils::contextMapToJava)
				.map(ContextResponse::new).map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.get();
	}

	/**
	 * 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)).get();
	}

	/**
	 * 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 UnitUnderTest context data for a TestStep", description = "Returns the complete context", responses = {
			@ApiResponse(responseCode = "200", description = "The UnitUnderTest context data", content = @Content(schema = @Schema(implementation = ContextResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/unitundertest")
	public Response findContextUUT(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id) {

		return contextService.getTestStepContext(V(sourceName), V(id), ContextType.UNITUNDERTEST)
				.map(ServiceUtils::contextMapToJava).map(ContextResponse::new)
				.map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK)).get();
	}

	/**
	 * Updates the context of {@link ContextType} UNITUNDERTEST 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 {@link ContextType} UNITUNDERTEST of the updated
	 *         {@link TestStep}
	 */
	@PUT
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/unitundertest")
	@RolesAllowed({ "write-user" })
	public Response updateContextUUT(@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, ContextType.UNITUNDERTEST))
				.map(ContextResponse::new).map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.get();
	}

	/**
	 * 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 TestSequence context data for a TestStep", description = "Returns the TestSequence context data", responses = {
			@ApiResponse(responseCode = "200", description = "The TestSequence context data", content = @Content(schema = @Schema(implementation = ContextResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/testsequence")
	public Response findContextTSQ(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id) {

		return contextService.getTestStepContext(V(sourceName), V(id), ContextType.TESTSEQUENCE)
				.map(ServiceUtils::contextMapToJava).map(ContextResponse::new)
				.map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK)).get();
	}

	/**
	 * Updates the context of {@link ContextType} TESTSEQUENCE 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 {@link ContextType} TESTSEQUENCE of the updated
	 *         {@link TestStep}
	 */
	@PUT
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/testsequence")
	@RolesAllowed({ "write-user" })
	public Response updateContextTSQ(@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, ContextType.TESTSEQUENCE))
				.map(ContextResponse::new).map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.get();
	}

	/**
	 * 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 TestEquipment context data for a TestStep", description = "Returns the TestEquipment context data", responses = {
			@ApiResponse(responseCode = "200", description = "The TestEquipment context data", content = @Content(schema = @Schema(implementation = ContextResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/testequipment")
	public Response findContextTEQ(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id) {

		return contextService.getTestStepContext(V(sourceName), V(id), ContextType.TESTEQUIPMENT)
				.map(ServiceUtils::contextMapToJava).map(ContextResponse::new)
				.map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK)).get();
	}

	/**
	 * Updates the context of {@link ContextType} TESTEQUIPMENT 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 {@link ContextType} TESTEQUIPMENT of the updated
	 *         {@link TestStep}
	 */
	@PUT
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/testequipment")
	@RolesAllowed({ "write-user" })
	public Response updateContextTEQ(@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, ContextType.TESTEQUIPMENT))
				.map(ContextResponse::new).map(contextResponse -> ServiceUtils.toResponse(contextResponse, Status.OK))
				.get();
	}

	/**
	 * 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 Sensor context data", description = "Returns the Sensor context data of TestEquipments", responses = {
			@ApiResponse(responseCode = "200", description = "The Sensor context data", content = @Content(schema = @Schema(implementation = ContextResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{" + REQUESTPARAM_ID + "}/contexts/testequipment/sensors")
	public Response getContextTEQSensors(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
			@PathParam(REQUESTPARAM_ID) String id) {

		return Try.of(() -> testStepService.getSensors(sourceName, id))
				.map(sensorMap -> ServiceUtils.toResponse(new ContextSensorResponse(sensorMap), Status.OK)).get();
	}

	/**
	 * delegates the request to the {@link TestStepService}
	 * 
	 * @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 TestStep localizations", description = "Returns TestStep localizations", responses = {
			@ApiResponse(description = "The TestStep localizations", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
			@ApiResponse(responseCode = "500", description = "Error") })
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/localizations")
	@Deprecated
	public Response localize(
			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {

		return Try
				.of(() -> new I18NResponse(testStepService.localizeType(sourceName),
						testStepService.localizeAttributes(sourceName)))
				.map(resp -> ServiceUtils.toResponse(resp, Status.OK)).get();
	}

	/**
	 * Returns the created {@link TestStep}.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param body       The {@link TestStep} to create.
	 * @return the created {@link TestStep} as {@link Response}.
	 */
	@POST
	@Operation(summary = "Create a new TestStep", responses = {
			@ApiResponse(description = "The created TestStep", 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) {

		return entityService
				.create(V(sourceName), TestStep.class,
						entityService.extractRequestBody(body, sourceName,
								List.of(Test.class, TemplateTestStep.class, Classification.class)))
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED)).get();
	}

	/**
	 * Updates the {@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 updated {@link TestStep}
	 */
	@PUT
	@Operation(summary = "Update an existing TestStep", description = "Updates the TestStep with all parameters set in the body of the request.", responses = {
			@ApiResponse(description = "The updated Project", 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 TestStep", required = true) @PathParam(REQUESTPARAM_ID) String id,
			String body) {
		RequestBody requestBody = RequestBody.create(body);

		return entityService
				.update(V(sourceName), entityService.find(V(sourceName), TestStep.class, V(id)),
						requestBody.getValueMapSupplier())
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).get();
	}

	/**
	 * Deletes and returns the deleted {@link TestStep}.
	 * 
	 * @param sourceName name of the source (MDM {@link Environment} name)
	 * @param id         The identifier of the {@link TestStep} to delete.
	 * @return the deleted {@link ValueList }s as {@link Response}
	 */
	@DELETE
	@Operation(summary = "Delete an existing TestStep", responses = {
			@ApiResponse(description = "The deleted TestStep", 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 TestStep", required = true) @PathParam(REQUESTPARAM_ID) String id) {
		return entityService.delete(V(sourceName), entityService.find(V(sourceName), TestStep.class, V(id)))
				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).get();
	}

	@Path("/{" + REQUESTPARAM_ID + "}/contexts/{" + REQUESTPARAM_CONTEXTTYPE + "}/{" + REQUESTPARAM_CONTEXTCOMPONENTNAME
			+ "}/{" + REQUESTPARAM_ATTRIBUTENAME + "}/files")
	public ContextFilesSubresource getContextFilesSubresource() {
		ContextFilesSubresource resource = resourceContext.getResource(ContextFilesSubresource.class);
		resource.setEntityClass(TestStep.class);
		return resource;
	}

	@Path("/{" + REQUESTPARAM_ID + "}/files")
	public FilesAttachableSubresource getFilesAttachableSubresource() {
		FilesAttachableSubresource resource = resourceContext.getResource(FilesAttachableSubresource.class);
		resource.setEntityClass(TestStep.class);
		return resource;
	}
}
