package eu.dnetlib.scholix.api.controller;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.dhp.schema.sx.api.model.v2.PageResultType;
import eu.dnetlib.dhp.schema.sx.api.model.v2.ScholixType;
import eu.dnetlib.dhp.schema.sx.scholix.Scholix;
import eu.dnetlib.scholix.api.ScholixException;
import eu.dnetlib.scholix.api.index.ScholixIndexManager;
import io.micrometer.core.annotation.Timed;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/v2")
@Tag(name = "Links : Operation related to the Scholix Links")
public class ScholixControllerV2 extends AbstractDnetController {

	@Autowired
	private ScholixIndexManager manager;

	@Timed(value = "scholix.v2.links", description = "Time taken to return links on Version 2.0 of Scholix")
	@Operation(summary = "Get Scholix Links")
	@GetMapping("/Links")
	public PageResultType links(
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships collected from a LinkProvider") final String linkProvider,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a target pid") final String targetPid,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a target pid type") final String targetPidType,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a target published in a Publisher named targetPublisher") final String targetPublisher,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a target type (literature, dataset, unknown)") final String targetType,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a source pid") final String sourcePid,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a source pid type") final String sourcePidType,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a source published in a Publisher named sourcePublisher") final String sourcePublisher,
			@RequestParam(required = false)
			@Parameter(in = ParameterIn.QUERY, description = "Filter Scholix relationships having a source type (literature, dataset, unknown)") final String sourceType,
		// @Parameter(in = ParameterIn.QUERY,
		// description = "Filter scholix Links having collected after this date") String harvestedAfter,
		@Parameter(in = ParameterIn.QUERY, description = "select page of result") final Integer page) throws Exception {

		if (StringUtils.isEmpty(sourcePid) && StringUtils.isEmpty(targetPid) && StringUtils.isEmpty(sourcePublisher) && StringUtils.isEmpty(targetPublisher)
			&& StringUtils.isEmpty(linkProvider)) {
			throw new ScholixException(
				"The method requires one of the following parameters: sourcePid, targetPid, sourcePublisher, targetPublisher, linkProvider");
		}

		try {
			final int currentPage = page != null ? page : 0;
			final Pair<Long, List<Scholix>> scholixResult = manager
				.linksFromPid(linkProvider, targetPid, targetPidType, targetPublisher, targetType, sourcePid, sourcePidType, sourcePublisher, sourceType, currentPage);
			final PageResultType pageResult = new PageResultType();
			pageResult.setTotalPages(scholixResult.getLeft().intValue() / 10);
			pageResult.setTotalLinks(scholixResult.getLeft().intValue());
			pageResult.setResult(scholixResult.getRight().stream().map(ScholixType::fromScholix).collect(Collectors.toList()));
			return pageResult;
		} catch (final Throwable e) {
			throw new ScholixException("Error on requesting url ", e);
		}
	}
}
