package eu.dnetlib.openaire.dsm;

import static eu.dnetlib.openaire.common.ExporterConstants.DS;
import static eu.dnetlib.openaire.common.ExporterConstants.R;

import java.util.List;

import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.dsm.dao.ResponseUtils;
import eu.dnetlib.openaire.exporter.exceptions.DsmApiException;
import eu.dnetlib.openaire.exporter.model.dsm.AggregationHistoryResponseV2;
import eu.dnetlib.openaire.exporter.model.dsm.SimpleDatasourceInfo;
import eu.dnetlib.openaire.exporter.model.dsm.SimpleResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@CrossOrigin(origins = {
	"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.dsm", havingValue = "true")
@Tag(name = "OpenAIRE DSM API (version 2.0)", description = "the OpenAIRE Datasource Manager API 2.0")
@RequestMapping("/dsm/2.0")
public class DsmApiControllerV2 extends AbstractExporterController {

	@Autowired
	private DsmCore dsmCore;

	@GetMapping("/recentregistered/{size}")
	@Operation(summary = "return the latest datasources that were registered through Provide (v2)", description = "Returns list of Datasource basic info.", tags = {
		DS,
		R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public SimpleResponse<SimpleDatasourceInfo> recentRegisteredV2(@PathVariable final int size) throws Throwable {
		final StopWatch stop = StopWatch.createStarted();
		final SimpleResponse<SimpleDatasourceInfo> rsp = dsmCore.searchRecentRegisteredV2(size);
		return prepareResponse(1, size, stop, rsp);
	}

	@GetMapping("/countfirstcollect")
	@Operation(summary = "return the number of datasources registered after the given date", description = "Returns a number.", tags = {
		DS,
		R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public Long countFirstCollectAfter(@RequestParam final String fromDate,
		@RequestParam(required = false) final String typologyFilter) throws Throwable {
		return dsmCore.countFirstCollect(fromDate, typologyFilter);
	}

	@GetMapping("/firstCollected")
	@Operation(summary = "return the datasources that were collected for the first time after the specified date", description = "Returns list of Datasource basic info.", tags = {
		DS,
		R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public SimpleResponse<SimpleDatasourceInfo> firstCollectedAfter(@RequestParam final String fromDate,
		@RequestParam(required = false) final String typologyFilter) throws Throwable {
		final StopWatch stop = StopWatch.createStarted();
		final List<SimpleDatasourceInfo> list = dsmCore.getFirstCollectedAfter(fromDate, typologyFilter);
		final SimpleResponse<SimpleDatasourceInfo> rsp = ResponseUtils.simpleResponse(list);

		return prepareResponse(1, list.size(), stop, rsp);
	}

	@GetMapping(value = "/aggregationhistory/{dsId}", produces = {
		"application/json"
	})
	@Operation(summary = "Return history", description = "Returns the aggregation history of the datasources (it includes also the failures)", tags = {
		DS, R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public AggregationHistoryResponseV2 aggregationHistory(@PathVariable final String dsId) throws DsmApiException {
		final StopWatch stop = StopWatch.createStarted();
		final AggregationHistoryResponseV2 rsp = dsmCore.aggregationhistoryV2(dsId);
		return prepareResponse(0, rsp.getAggregationInfo().size(), stop, rsp);
	}

}
