/**
 * 
 */
package eu.dnetlib.dlms.impl.daos;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openrdf.model.Value;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import eu.dnetlib.dlms.config.SystemSetsNames;
import eu.dnetlib.dlms.impl.hibobjects.RepositoryWrapper;
import eu.dnetlib.dlms.lowlevel.objects.Set;
import eu.dnetlib.dlms.lowlevel.objects.structures.Structure;
import eu.dnetlib.dlms.lowlevel.types.AtomType;
import eu.dnetlib.dlms.lowlevel.types.AtomTypeDAO;
import eu.dnetlib.dlms.lowlevel.types.SetType;
import eu.dnetlib.dlms.lowlevel.types.SetTypeDAO;

/**
 * @author lexis
 * 
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ExtSetDAOHibernateTest {

	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(ExtSetDAOHibernateTest.class);

	@Resource
	private ExtSetDAOHibernate extSetDAO;

	@Resource
	private AtomTypeDAO atomTypeDAO;
	/** DAO for SetType. */
	@Resource
	private SetTypeDAO setTypeDAO;
	/** DAO for UnionSetType. */

	/** AtomType. */
	@Resource
	private AtomType atomType1;

	/**
	 *setType1 has contentType atomType1.
	 */
	@Resource
	private SetType setType1;
	/** The union set type. */

	/**
	 * Sets to contain atoms. atomSet1 has setType setType1
	 */
	@Resource
	private Set atomSet1;

	@Resource
	private RepositoryWrapper repositoryWrapper;

	public void logTriples() throws RepositoryException {
		final RepositoryConnection c = this.repositoryWrapper.getConnection();
		final RepositoryResult<org.openrdf.model.Statement> res = c.getStatements(null, null, (Value) null, false);
		int count = 0;
		while (res.hasNext()) {
			log.debug(res.next());
			count++;
		}
		log.debug("Total number of triples: " + count);
		res.close();
		c.close();
	}

	/**
	 * Before the test let's save a type, settype and set.
	 * 
	 * @throws RepositoryException
	 */
	@Before
	public void init() throws RepositoryException {
		this.atomTypeDAO.save(this.atomType1);
		this.setTypeDAO.save(this.setType1);
		this.extSetDAO.save(this.atomSet1);
		this.logTriples();
	}

	/**
	 * Test method for {@link eu.dnetlib.dlms.impl.daos.ExtSetDAOHibernate#delete(eu.dnetlib.dlms.lowlevel.objects.Set)}
	 * .
	 * 
	 * @throws RepositoryException
	 */
	@Test
	@DirtiesContext
	public void testDeleteSet() throws RepositoryException {
		//first let's check there is an entry for atomSet1 in systemAtomSets
		final Set systemAtomSets = this.extSetDAO.getSetByName(SystemSetsNames.ATOM_SETS);
		this.logTriples();
		Structure s = this.extSetDAO.getSystemSetHelper().findStructureForSet(this.atomSet1.getId(), systemAtomSets);
		assertNotNull(s);
		log.debug(s);
		//now let's delete atomSet1
		this.extSetDAO.delete(this.atomSet1);
		//now let's check if the entry is not there anymore!
		s = this.extSetDAO.getSystemSetHelper().findStructureForSet(this.atomSet1.getId(), systemAtomSets);
		assertNull(s);
	}

	/**
	 * Test method for {@link eu.dnetlib.dlms.impl.daos.ExtSetDAOHibernate#delete(long)}.
	 */
	@Test
	@DirtiesContext
	public void testDeleteLong() {
		//first let's check there is an entry for atomSet1 in systemAtomSets
		final Set systemAtomSets = this.extSetDAO.getSetByName(SystemSetsNames.ATOM_SETS);
		Structure s = this.extSetDAO.getSystemSetHelper().findStructureForSet(this.atomSet1.getId(), systemAtomSets);
		assertNotNull(s);
		log.debug(s);
		//now let's delete atomSet1
		this.extSetDAO.delete(this.atomSet1.getId());
		//now let's check if the entry is not there anymore!
		s = this.extSetDAO.getSystemSetHelper().findStructureForSet(this.atomSet1.getId(), systemAtomSets);
		assertNull(s);
	}

	/**
	 * Test method for {@link eu.dnetlib.dlms.impl.daos.ExtSetDAOHibernate#save(eu.dnetlib.dlms.lowlevel.objects.Set)}.
	 */
	@Test
	@DirtiesContext
	public void testSaveSet() {
		final SetType setType2 = this.setTypeDAO.create(this.atomType1);
		setType2.setName("atomSet2");
		this.setTypeDAO.save(setType2);
		final Set atomSet2 = this.extSetDAO.create();
		atomSet2.setInfo("atomSet2 for testSaveSet of enhanced SetDAO");
		atomSet2.setObjectType(setType2);
		this.extSetDAO.save(atomSet2);

		//first let's check there is an entry for atomSet1 in systemAtomSets
		final Set systemAtomSets = this.extSetDAO.getSetByName(SystemSetsNames.ATOM_SETS);
		final Structure s = this.extSetDAO.getSystemSetHelper().findStructureForSet(atomSet2.getId(), systemAtomSets);
		assertNotNull(s);
		log.debug(s);
	}

}
