package eu.dnetlib.dlms.impl.daos;

import org.springframework.beans.factory.annotation.Required;

import eu.dnetlib.dlms.config.SystemSetsHelper;
import eu.dnetlib.dlms.config.SystemSetsNames;
import eu.dnetlib.dlms.impl.hibobjects.RelationSetDAOHibernate;
import eu.dnetlib.dlms.lowlevel.objects.Relation;
import eu.dnetlib.dlms.lowlevel.objects.RelationDAO;
import eu.dnetlib.dlms.lowlevel.objects.RelationSet;
import eu.dnetlib.dlms.lowlevel.objects.WrapperDAO;
import eu.dnetlib.dlms.lowlevel.objects.structures.Structure;
import eu.dnetlib.dlms.lowlevel.types.RelationType;
import eu.dnetlib.dlms.lowlevel.types.RelationTypeDAO;

/**
 * @author lexis
 * 
 */
public class ExtRelationSetDAOHibernate extends RelationSetDAOHibernate {

	private SystemSetsHelper systemSetHelper;
	private RelationTypeDAO relTypeDAO;
	private WrapperDAO wrapperDAO;
	private RelationDAO relDAO;

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.dlms.impl.hibobjects.RelationSetDAOHibernate#delete(eu.dnetlib.dlms.lowlevel.objects.RelationSet)
	 */
	@Override
	public void delete(final RelationSet theRelSet) {
		this.systemSetHelper.removeSystemEntryFor(theRelSet);
		super.delete(theRelSet);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.dlms.impl.hibobjects.RelationSetDAOHibernate#save(eu.dnetlib.dlms.lowlevel.objects.RelationSet)
	 */
	@Override
	public void save(final RelationSet theSet) {
		//saves in system set only the first time!
		if (theSet.getId() == 0) {
			super.save(theSet);
			//final UnionSet systemAllSets = this.systemSetHelper.getUnionSetDAO().getUnionSetByName(SystemSetsNames.ALL_SETS);
			//1. create and save a Structure that represents set in the SystemRelSets Set and add it to SystemSets.
			final Structure systemStructure = this.systemSetHelper.createStructureFor(theSet);
			final RelationType hasFstSetType = this.relTypeDAO.getByName(SystemSetsNames.TYPE_HAS_FST_SET);

			final RelationSet hasFstRelSet = this.getRelationSetByLabel(SystemSetsNames.HAS_FST_SET);
			//2a. adds a relation to the structure that represents first set
			final Structure fstSystemStruct = this.systemSetHelper.findSystemStructureFor(theSet.getFstSet());
			//relation:
			final Relation hasFstRel = this.relDAO.create();
			hasFstRel.setFstObj(systemStructure);
			hasFstRel.setSndObj(fstSystemStruct);
			hasFstRel.setObjectType(hasFstSetType);
			this.relDAO.save(hasFstRel);
			this.addToSet(hasFstRelSet, hasFstRel);
			this.relDAO.save(hasFstRel);
			super.save(hasFstRelSet);

			//2b. adds a relation to the structure that represents snd set
			final Structure sndSystemStruct = this.systemSetHelper.findSystemStructureFor(theSet.getSndSet());
			final RelationType hasSndSetType = this.relTypeDAO.getByName(SystemSetsNames.TYPE_HAS_SND_SET);
			final RelationSet hasSndRelSet = this.getRelationSetByLabel(SystemSetsNames.HAS_SND_SET);
			//relation:
			final Relation hasSndRel = this.relDAO.create();
			hasSndRel.setFstObj(systemStructure);
			hasSndRel.setSndObj(sndSystemStruct);
			hasSndRel.setObjectType(hasSndSetType);
			this.relDAO.save(hasSndRel);
			this.addToSet(hasSndRelSet, hasSndRel);
			this.relDAO.save(hasSndRel);
			super.save(hasSndRelSet);
		} else
			super.save(theSet);
	}

	@Required
	public void setSystemSetHelper(final SystemSetsHelper systemSetHelper) {
		this.systemSetHelper = systemSetHelper;
	}

	public SystemSetsHelper getSystemSetHelper() {
		return this.systemSetHelper;
	}

	@Required
	public void setRelTypeDAO(final RelationTypeDAO relTypeDAO) {
		this.relTypeDAO = relTypeDAO;
	}

	public RelationTypeDAO getRelTypeDAO() {
		return this.relTypeDAO;
	}

	@Required
	public void setWrapperDAO(final WrapperDAO wrapperDAO) {
		this.wrapperDAO = wrapperDAO;
	}

	public WrapperDAO getWrapperDAO() {
		return this.wrapperDAO;
	}

	@Required
	public void setRelDAO(final RelationDAO relDAO) {
		this.relDAO = relDAO;
	}

	public RelationDAO getRelDAO() {
		return this.relDAO;
	}

}
