package eu.dnetlib.index.action;

import eu.dnetlib.utils.MetadataReference;
import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
import eu.dnetlib.enabling.tools.blackboard.BlackboardServerAction;
import eu.dnetlib.enabling.tools.blackboard.BlackboardServerHandler;
import eu.dnetlib.index.IndexBackendDescriptor;
import eu.dnetlib.index.IndexBackendEnumerator;
import eu.dnetlib.index.IndexServerDAOMap;
import eu.dnetlib.rmi.provision.IndexServiceException;
import org.antlr.stringtemplate.StringTemplate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

/**
 * The Class manage the blackboard action of Create Index.
 */
public class CreateIndexAction extends AbstractIndexAction implements BlackboardServerAction<IndexAction> {

	private static final Log log = LogFactory.getLog(CreateIndexAction.class);

	@Autowired
	private IndexServerDAOMap indexServerDAOMap;

	@Autowired
	private IndexBackendEnumerator backendEnumerator;

	/**
	 * index ds template.
	 */
	private transient StringTemplate indexDsTemplate;

	/**
	 * {@inheritDoc}
	 *
	 * @see BlackboardServerAction#execute(BlackboardServerHandler,
	 * BlackboardJob)
	 */
	@Override
	public void execute(final BlackboardServerHandler handler, final BlackboardJob job) throws IndexServiceException {
		final MetadataReference mdRef = getMetadataReference(job);
		if ((mdRef.getFormat() == null) || (mdRef.getLayout() == null))
			throw new IndexServiceException("some Blackboard parameter is missing in CREATE message");
		final String fields = getMDFormatFields(mdRef);

		if (fields.isEmpty()) throw new IndexServiceException("No result getting index layout informations");

		final String backendId = getBackend(job);
		if (backendId == null) throw new IndexServiceException("No backend identifier information in CREATE message");

		final String dataStructure = getDataStructure(mdRef, backendId);
		final String newId = serviceTools.registerProfile(dataStructure);
		log.info("registered DsId: " + newId + "\n" + dataStructure);

		indexServerDAOMap.getIndexServerDAO(backendId).createIndexCollection(mdRef, fields);

		serviceTools.incrementHandledDataStructures(backendId);
		job.getParameters().put("id", newId);
		handler.done(job);

	}

	/**
	 * Method applies given format, layout and interpretation to the index dataStructure template.
	 *
	 * @return String representation of the indexDataStructure
	 * @throws IndexServiceException
	 */
	private String getDataStructure(final MetadataReference mdRef, final String backendIdentifier) throws IndexServiceException {

		final StringTemplate ds = new StringTemplate(indexDsTemplate.getTemplate());

		IndexBackendDescriptor backendDescriptor = backendEnumerator.getDescriptor(backendIdentifier);
		if (backendDescriptor == null) throw new IndexServiceException("No backend identifier found id:" + backendIdentifier);
		String backendName = backendDescriptor.getEndpoint().get(IndexBackendDescriptor.ID);
		if (backendName == null) throw new IndexServiceException("No backend name associtated to the  identifier with id:" + backendIdentifier);
		ds.setAttribute("serviceUri", getServiceAddress(backendIdentifier));
		ds.setAttribute("format", mdRef.getFormat());
		ds.setAttribute("layout", mdRef.getLayout());
		ds.setAttribute("interpretation", mdRef.getInterpretation());
		ds.setAttribute("backendID", backendIdentifier);
		ds.setAttribute("backendNAME", backendName);
		return ds.toString();
	}

	@Required
	public void setIndexDsTemplate(final StringTemplate indexDsTemplate) {
		this.indexDsTemplate = indexDsTemplate;
	}

}
