/********************************************************************************
 * 
 * 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.utils.Decomposer.decompose;

import java.util.Map;

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.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.dflt.model.Pool;
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.I18NResponse;
import org.eclipse.mdm.businessobjects.entity.MDMEntity;
import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
import org.eclipse.mdm.businessobjects.entity.SearchAttributeResponse;
import org.eclipse.mdm.businessobjects.service.EntityFileLink;
import org.eclipse.mdm.businessobjects.service.EntityService;
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.collection.List;
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 Logger LOG = LoggerFactory.getLogger(TestResource.class);

	@EJB
	private TestService testService;

	@EJB
	private EntityService entityService;

	@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(sourceName, Test.class, 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,
			MDMEntityResponse body) {

		return entityService
				.create(sourceName, Test.class,
						entityService.extractArgumentsFromRequestBody(sourceName, body, List.of("Name"),
								List.of(Pool.class, TemplateTest.class)))
				.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}
	 */
	@POST
	@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 + "}")
	public Response patch(
			@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,
			MDMEntityResponse body) {

		return entityService
				.update(sourceName, entityService.find(sourceName, Test.class, id),
						decompose(body::getData).<MDMEntity>getValueAt(0))
				.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(sourceName, entityService.find(sourceName, Test.class, 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(sourceName, Test.class, 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);
	}
}
