package eu.dnetlib.enabling.inspector;

import java.io.File;
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.xml.sax.SAXException;
import org.xmldb.api.base.XMLDBException;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.enabling.tools.ResourceIdentifierResolver;
import eu.dnetlib.enabling.tools.ServiceLocator;
import eu.dnetlib.enabling.tools.StringOpaqueResource;
import eu.dnetlib.xml.database.XMLDatabase;

/**
 * Implement mid-level functionality for validation and invalidation of profiles browsed with the ResourceTreeController.
 *
 * @see ResourceTreeController
 * @author marko
 *
 */
@Controller
public class ValidationController extends AbstractInspectorController  {
	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(ValidationController.class); // NOPMD by marko on 11/24/08 5:02 PM

	/**
	 * base index.do path.
	 */
	private static final String INDEX_DO = "/inspector/index.do";

	/**
	 * xml database.
	 */
	@Resource(name = "existDatabase")
	private transient XMLDatabase xmlDatabase;

	/**
	 * IS lookup service locator.
	 */
	@Resource(name = "lookupLocator")
	private transient ServiceLocator<ISLookUpService> lookUpLocator;

	/**
	 * IS registry service locator.
	 */
	@Resource(name = "registryLocator")
	private transient ServiceLocator<ISRegistryService> registryLocator;

	/**
	 * resolve xmldb ids to resource ids.
	 */
	@Resource
	private transient ResourceIdentifierResolver resIdResolver;

	/**
	 * high level: profile validation via registry.
	 *
	 * @param model
	 *            model
	 * @param request
	 *            request
	 * @return view name
	 * @throws XMLDBException
	 *             happens
	 * @throws ParserConfigurationException shouldn't happen
	 * @throws IOException shouldn't happen
	 * @throws SAXException shouldn't happen
	 * @throws XPathExpressionException shouldn't happen
	 * @throws ISRegistryException happens
	 * @throws ISLookUpException happens
	 */
	@RequestMapping("/inspector/index.do/**/validate")
	String validate(final Model model, final HttpServletRequest request) throws XMLDBException, XPathExpressionException, SAXException, IOException, ParserConfigurationException, ISRegistryException, ISLookUpException {

		final String path = request.getPathInfo().replace(INDEX_DO, "").replace("/validate", "");

		final File fileHelper = new File(path);
		final String collection = fileHelper.getParent();
		final String fileName = fileHelper.getName();

		log.info("validating: " + path);
		final OpaqueResource resource = new StringOpaqueResource(xmlDatabase.read(fileName, collection));
		log.info("validating a " + resource.getResourceType());

		final String newId = registryLocator.getService().validateProfile(resource.getResourceId());
		final OpaqueResource valid = new StringOpaqueResource(lookUpLocator.getService().getResourceProfile(newId));

		final String vFileName = resIdResolver.getFileName(valid.getResourceId());
		final String vCollectionName = resIdResolver.getCollectionName(valid.getResourceId());

		return "redirect:../../../" + vCollectionName + "/" + vFileName + "/show";
	}

	/**
	 * high level: profile invalidation via registry.
	 *
	 * @param model
	 *            model
	 * @param request
	 *            request
	 * @return view name
	 * @throws XMLDBException
	 *             happens
	 * @throws ParserConfigurationException shouldn't happen
	 * @throws IOException shouldn't happen
	 * @throws SAXException shouldn't happen
	 * @throws XPathExpressionException shouldn't happen
	 * @throws ISRegistryException happens
	 * @throws ISLookUpException happens
	 */
	@RequestMapping("/inspector/index.do/**/invalidate")
	String invalidate(final Model model, final HttpServletRequest request) throws XMLDBException, XPathExpressionException, SAXException, IOException, ParserConfigurationException, ISRegistryException, ISLookUpException {

		final String path = request.getPathInfo().replace(INDEX_DO, "").replace("/invalidate", "");

		final File fileHelper = new File(path);
		final String collection = fileHelper.getParent();
		final String fileName = fileHelper.getName();

		log.info("invalidating: " + path);
		final OpaqueResource resource = new StringOpaqueResource(xmlDatabase.read(fileName, collection));
		log.info("invalidating a " + resource.getResourceType());

		final String newId = registryLocator.getService().invalidateProfile(resource.getResourceId());
		final OpaqueResource invalid = new StringOpaqueResource(lookUpLocator.getService().getResourceProfile(newId));

		final String vFileName = resIdResolver.getFileName(invalid.getResourceId());
		final String vCollectionName = resIdResolver.getCollectionName(invalid.getResourceId());

		return "redirect:../../../" + vCollectionName + "/" + vFileName + "/show";
	}

}
