package eu.dnetlib.openaire.info;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.common.ExporterConstants;
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.info", havingValue = "true")
@Tag(name = "OpenAIRE Info API", description = "the OpenAIRE info API")
public class InfoController extends AbstractExporterController {

	private static final Log log = LogFactory.getLog(InfoController.class); // NOPMD by marko on 11/24/08 5:02 PM

	public final static String UTF8 = "UTF-8";

	@Autowired
	private JdbcInfoDao jdbcInfoDao;

	@RequestMapping(value = "/info/{infoKey}", produces = {
		"application/json"
	}, method = RequestMethod.GET)
	@Operation(summary = "get info date", description = "get info date", tags = {
		ExporterConstants.R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public LocalDate getDate(@PathVariable final String infoKey) {
		final JdbcInfoDao.DATE_INFO info = JdbcInfoDao.DATE_INFO.valueOf(infoKey);
		if (info == null) { throw new RuntimeException(infoKey + " not recognized"); }
		return jdbcInfoDao.getDate(info);
	}

	@RequestMapping(value = "/info", produces = {
		"application/json"
	}, method = RequestMethod.GET)
	@Operation(summary = "get all the info date", description = "get all the info date", tags = {
		ExporterConstants.R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public Map<String, LocalDate> listInfo() {
		final Map<String, LocalDate> map = Maps.newHashMap();
		for (final JdbcInfoDao.DATE_INFO dateInfo : JdbcInfoDao.DATE_INFO.values()) {
			map.put(dateInfo.name(), jdbcInfoDao.getDate(dateInfo));
		}
		return map;
	}

	@RequestMapping(value = "/info/keys", produces = {
		"application/json"
	}, method = RequestMethod.GET)
	@Operation(summary = "get the available keys", description = "get the available keys", tags = {
		ExporterConstants.R
	})
	@ApiResponses(value = {
		@ApiResponse(responseCode = "200", description = "OK"),
		@ApiResponse(responseCode = "500", description = "unexpected error")
	})
	public List<String> listInfoKeys() {
		final List<String> keys = Lists.newArrayList();
		for (final JdbcInfoDao.DATE_INFO dateInfo : JdbcInfoDao.DATE_INFO.values()) {
			keys.add(dateInfo.name());
		}
		return keys;
	}

	@RequestMapping(value = "/info/dropCache", produces = {
		"application/json"
	}, method = RequestMethod.GET)
	@Operation(summary = "Drops the info cache", description = "Drops the info cache", tags = {
		ExporterConstants.R
	})
	public void dropCache() {
		jdbcInfoDao.dropCache();
	}

}
