package eu.dnetlib.enabling.datasources;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import eu.dnetlib.clients.dsManager.BrowsableField;
import eu.dnetlib.clients.dsManager.BrowseTerm;
import eu.dnetlib.clients.dsManager.DatasourceDesc;
import eu.dnetlib.clients.dsManager.DatasourcePoint;
import eu.dnetlib.clients.dsManager.IfaceDesc;
import eu.dnetlib.clients.dsManager.SearchInterfacesEntry;
import eu.dnetlib.clients.dsManager.SimpleDatasourceDesc;
import eu.dnetlib.enabling.annotations.DnetService;
import eu.dnetlib.enabling.annotations.DnetServiceType;
import eu.dnetlib.services.BaseService;

@RestController
@RequestMapping(value = "/dsManager")
@DnetService(DnetServiceType.dsManager)
public class DatasourceManagerController extends BaseService {

	@Autowired
	private DatasourceManagerCore core;

	@RequestMapping(value = "map", method = RequestMethod.GET)
	public List<DatasourcePoint> getRepositoryMap() throws DatasourceManagerServiceException {
		return core.getDatasourceMap();
	}

	@RequestMapping(value = "ds/{type}", method = RequestMethod.GET)
	public List<SimpleDatasourceDesc> simpleListDatasourcesByType(@PathVariable final String type) throws DatasourceManagerServiceException {
		return core.simpleListDatasourcesByType(type);
	}

	@RequestMapping(value = "ds", method = RequestMethod.POST)
	public String addDatasource(@RequestBody final DatasourceDesc ds) throws DatasourceManagerServiceException {
		return core.addDatasource(ds);
	}

	@RequestMapping(value = "ds", method = RequestMethod.DELETE)
	public boolean deleteDatasource(@RequestParam final String dsId) throws DatasourceManagerServiceException {
		return core.deleteDatasource(dsId);
	}

	@RequestMapping(value = "ds", method = RequestMethod.GET)
	public DatasourceDesc getDatasource(@RequestParam final String dsId) throws DatasourceManagerServiceException {
		return core.getDatasource(dsId);
	}

	@RequestMapping(value = "search/ds", method = RequestMethod.GET)
	public List<DatasourceDesc> listDatasources(
			@RequestParam(required = false) final String compliance,
			@RequestParam(required = false) final String contentDescription,
			@RequestParam(required = false) final String collectedFrom) throws DatasourceManagerServiceException {
		return core.listDatasources(compliance, contentDescription, collectedFrom);
	}

	@RequestMapping(value = "api/compliance", method = RequestMethod.GET)
	public boolean updateLevelOfCompliance(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestParam(required = false, defaultValue = "") final String level,
			@RequestParam(required = false, defaultValue = "false") final boolean override) throws DatasourceManagerServiceException {

		if (override && StringUtils.isBlank(level)) {
			return core.resetLevelOfCompliance(dsId, ifaceId);
		} else {
			return core.updateLevelOfCompliance(dsId, ifaceId, level, override);
		}
	}

	@RequestMapping(value = "api/baseUrl", method = RequestMethod.GET)
	public boolean updateBaseUrl(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestParam final String baseUrl)
			throws DatasourceManagerServiceException {
		return core.updateBaseUrl(dsId, ifaceId, baseUrl);
	}

	@RequestMapping(value = "api/activation", method = RequestMethod.GET)
	public boolean updateActivationStatus(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestParam final boolean active) throws DatasourceManagerServiceException {
		return core.updateActivationStatus(dsId, ifaceId, active);
	}

	@RequestMapping(value = "api/contentDescr", method = RequestMethod.GET)
	public boolean updateContentDescription(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestParam final String desc) throws DatasourceManagerServiceException {
		return core.updateContentDescription(dsId, ifaceId, desc);
	}

	@RequestMapping(value = "api/extraField/{field}", method = RequestMethod.GET)
	public boolean updateExtraField(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@PathVariable final String field,
			@RequestParam final String value,
			@RequestParam(required = false, defaultValue = "true") final boolean preserveOriginal) throws DatasourceManagerServiceException {
		return core.updateExtraField(dsId, ifaceId, field, value, preserveOriginal);
	}

	@RequestMapping(value = "api/extraField/{field}", method = RequestMethod.DELETE)
	public boolean deleteExtraField(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@PathVariable final String field) throws DatasourceManagerServiceException {
		return core.deleteExtraField(dsId, ifaceId, field);
	}

	@RequestMapping(value = "api/accessParam/{field}", method = RequestMethod.GET)
	public boolean updateAccessParam(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@PathVariable final String field,
			@RequestParam final String value,
			@RequestParam(required = false, defaultValue = "true") final boolean preserveOriginal) throws DatasourceManagerServiceException {
		return core.updateAccessParam(dsId, ifaceId, field, value, preserveOriginal);
	}

	@RequestMapping(value = "api/accessParam/{field}", method = RequestMethod.DELETE)
	public boolean deleteAccessParam(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@PathVariable final String field) throws DatasourceManagerServiceException {
		return core.deleteAccessParam(dsId, ifaceId, field);
	}

	@RequestMapping(value = "api", method = RequestMethod.POST)
	public boolean addInterface(@RequestParam final String dsId, @RequestBody final IfaceDesc iface) throws DatasourceManagerServiceException {
		return core.addInterface(dsId, iface);
	}

	@RequestMapping(value = "api", method = RequestMethod.DELETE)
	public boolean deleteInterface(@RequestParam final String dsId, @RequestParam final String ifaceId) throws DatasourceManagerServiceException {
		return core.deleteInterface(dsId, ifaceId);
	}

	@RequestMapping(value = "api/nextScheduledExecution", method = RequestMethod.GET)
	public Date findNextScheduledExecution(@RequestParam final String dsId, @RequestParam final String ifaceId) throws DatasourceManagerServiceException {
		return core.findNextScheduledExecution(dsId, ifaceId);
	}

	@RequestMapping(value = "api/extraFields", method = RequestMethod.POST)
	public boolean bulkUpdateApiExtraFields(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestBody final Map<String, String> fields) throws DatasourceManagerServiceException {
		return core.bulkUpdateApiExtraFields(dsId, ifaceId, fields);
	}

	@RequestMapping(value = "api/accessParams", method = RequestMethod.POST)
	public boolean bulkUpdateApiAccessParams(@RequestParam final String dsId,
			@RequestParam final String ifaceId,
			@RequestBody final Map<String, String> params) throws DatasourceManagerServiceException {
		return core.bulkUpdateApiAccessParams(dsId, ifaceId, params);
	}

	@RequestMapping(value = "browse/api/fields", method = RequestMethod.GET)
	public List<BrowsableField> listBrowsableFields() throws DatasourceManagerServiceException {
		return core.listBrowsableFields();
	}

	@RequestMapping(value = "browse/api/{field}", method = RequestMethod.GET)
	public List<BrowseTerm> browseField(@PathVariable final String field) throws DatasourceManagerServiceException {
		return core.browseField(field);
	}

	@RequestMapping(value = "search/api/{field}", method = RequestMethod.GET)
	public List<SearchInterfacesEntry> searchInterface(@PathVariable final String field, @RequestParam final String value)
			throws DatasourceManagerServiceException {
		return core.searchInterface(field, value);
	}

}
