package org.sagebionetworks.repo.manager.doi;

import static org.mockito.Mockito.mock;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.sagebionetworks.doi.DoiClient;
import org.sagebionetworks.doi.EzidAsyncClient;
import org.sagebionetworks.repo.manager.NodeManager;
import org.sagebionetworks.repo.model.DoiAdminDao;
import org.sagebionetworks.repo.model.EntityType;
import org.sagebionetworks.repo.model.Node;
import org.sagebionetworks.repo.model.UserInfo;
import org.sagebionetworks.repo.model.dbo.dao.StorageLocationDAOImpl;
import org.sagebionetworks.repo.model.doi.Doi;
import org.sagebionetworks.repo.model.doi.DoiStatus;
import org.sagebionetworks.repo.web.util.UserProvider;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.ReflectionTestUtils;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-context.xml" })
public class EntityDoiManagerImplAutowiredTest {

	@Autowired private EntityDoiManager entityDoiManager;
	@Autowired private NodeManager nodeManager;
	@Autowired private UserProvider userProvider;
	@Autowired private DoiAdminDao doiAdminDao;
	private UserInfo testUserInfo;
	private List<String> toClearList;

	@Before
	public void before() throws Exception {

		assertNotNull(entityDoiManager);
		assertNotNull(nodeManager);
		assertNotNull(userProvider);
		assertNotNull(doiAdminDao);

		testUserInfo = userProvider.getTestUserInfo();
		assertNotNull(testUserInfo);

		// Inject a mock DOI client
		// If the DOI already exists, EZID will return an error
		// We want to avoid the error, thus the mocking
		DoiClient mockDoiClient = mock(EzidAsyncClient.class);
		EntityDoiManager toInject = entityDoiManager;
		if(AopUtils.isAopProxy(toInject) && toInject instanceof Advised) {
			Object target = ((Advised)toInject).getTargetSource().getTarget();
			toInject = (EntityDoiManager)target;
		}
		ReflectionTestUtils.setField(toInject, "ezidAsyncClient", mockDoiClient);

		toClearList = new ArrayList<String>();
	}

	@After
	public void after() throws Exception {
		for (String nodeId : toClearList) {
			nodeManager.delete(userProvider.getTestAdminUserInfo(), nodeId);
		}
		doiAdminDao.clear();
	}

	@Test
	public void testRoundTrip() throws Exception {
		Node node = new Node();
		final String nodeName = "EntityDoiManagerImplAutowiredTest.testRoundTrip()";
		node.setName(nodeName);
		node.setNodeType(EntityType.project.name());
		final String nodeId = nodeManager.createNewNode(node, testUserInfo);
		toClearList.add(nodeId);
		assertNotNull(nodeId);
		Doi doiCreate = entityDoiManager.createDoi(
				testUserInfo.getIndividualGroup().getName(), nodeId, null);
		assertNotNull(doiCreate);
		assertEquals(DoiStatus.IN_PROCESS, doiCreate.getDoiStatus());
		Thread.sleep(1000L);
		Doi doiGet = entityDoiManager.getDoi(
				testUserInfo.getIndividualGroup().getName(), nodeId, null);
		assertNotNull(doiGet);
	}
}

@@ -44,48 +44,8 @@
 i;%0A%0A
-import static org.mockito.Mockito.mock;%0A
 impo
@@ -130,16 +130,99 @@
 NotNull;
+%0Aimport static org.junit.Assert.assertNull;%0Aimport static org.mockito.Mockito.mock;
 %0A%0Aimport
@@ -751,37 +751,14 @@
 el.d
-bo.dao.StorageLocationDAOImpl
+oi.Doi
 ;%0Aim
@@ -792,32 +792,42 @@
 po.model.doi.Doi
+ObjectType
 ;%0Aimport org.sag
@@ -2740,16 +2740,17 @@
 ption %7B%0A
+%0A
 %09%09Node n
@@ -3042,16 +3042,17 @@
 odeId);%0A
+%0A
 %09%09Doi do
@@ -3181,16 +3181,384 @@
 reate);%0A
+%09%09assertNotNull(doiCreate.getId());%0A%09%09assertEquals(nodeId, doiCreate.getObjectId());%0A%09%09assertEquals(DoiObjectType.ENTITY, doiCreate.getDoiObjectType());%0A%09%09assertNull(doiCreate.getObjectVersion());%0A%09%09assertNotNull(doiCreate.getCreatedOn());%0A%09%09assertEquals(testUserInfo.getIndividualGroup().getId(), doiCreate.getCreatedBy());%0A%09%09assertNotNull(doiCreate.getUpdatedOn());%0A
 %09%09assert
@@ -3617,30 +3617,8 @@
 ));%0A
-%09%09Thread.sleep(1000L);
 %0A%09%09D
@@ -3743,13 +3743,421 @@
 oiGet);%0A
+%09%09assertNotNull(doiGet.getId());%0A%09%09assertEquals(nodeId, doiGet.getObjectId());%0A%09%09assertEquals(DoiObjectType.ENTITY, doiGet.getDoiObjectType());%0A%09%09assertNull(doiGet.getObjectVersion());%0A%09%09assertNotNull(doiGet.getCreatedOn());%0A%09%09assertEquals(testUserInfo.getIndividualGroup().getId(), doiGet.getCreatedBy());%0A%09%09assertNotNull(doiGet.getUpdatedOn());%0A%09%09assertEquals(DoiStatus.IN_PROCESS, doiGet.getDoiStatus());%0A
 %09%7D%0A%7D%0A

Add more testing