package gov.va.med.mpn.codedcontrols;

import gov.va.med.mpn.codedcontrol.CodedControl;
import gov.va.med.mpn.codedcontrol.impl.CodedControlService;
import gov.va.med.mpn.codedcontrol.model.UserResponse;
import gov.va.med.mpn.dao.interfaces.CategoryDAO;
import gov.va.med.mpn.dao.interfaces.ClassificationDAO;
import gov.va.med.mpn.dao.interfaces.CodedControlDataDAO;
import gov.va.med.mpn.entity.pojo.Category;
import gov.va.med.mpn.entity.pojo.Classification;
import gov.va.med.mpn.entity.pojo.CodedControlData;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.transport.local.LocalConduit;
import org.easymock.EasyMock;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import org.easymock.EasyMock;

import org.springframework.test.util.ReflectionTestUtils;



/**
 * The Class CodedControlsServiceTest.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:mpn-service-spring-beans-test.xml","classpath:spring-beans-dao-test.xml"})
public class CodedControlsServiceTest extends Assert {
	

	
	/** The Constant ENDPOINT_ADDRESS. */
	private final static String ENDPOINT_ADDRESS = "local://codedcontrolservice";
	
	/** The server. */
	private static Server server;
	
	
	@Resource(name="classificationDAO")
	protected ClassificationDAO classificationDao;
	
	@Resource(name="codedControlDataDAO")
	protected CodedControlDataDAO codedControlDataDAO;
	
	@Resource(name="categoryDAO")
	protected CategoryDAO categoryDAO;
	
    //@Autowired
    private CodedControl service;
	
	/**
	 * Initialize.
	 *
	 * @throws Exception the exception
	 */
	@BeforeClass
	public static void initialize() throws Exception {
	   //  startServer();
	}
	
	/**
	 * Start server.
	 *
	 * @throws Exception the exception
	 */
	private static void startServer() throws Exception {
	     JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
	     sf.setResourceClasses(CodedControlService.class);
	         
	     List<Object> providers = new ArrayList<Object>();
	     // add custom providers if any
	     sf.setProviders(providers);
	         
	     sf.setResourceProvider(CodedControlService.class,
	                            new SingletonResourceProvider(new CodedControlService(), true));
	     sf.setAddress(ENDPOINT_ADDRESS);
	 
	     server = sf.create();
	}
	
	/**
	 * Destroy.
	 *
	 * @throws Exception the exception
	 */
	@AfterClass
	public static void destroy() throws Exception {
	 //  server.stop();
	 //  server.destroy();
	}
	
	/**
	 * Test fetch control.
	 */
	@Test
	public void testFetchControl() {
		

	// client.path("codedcontrolservice/control/name/heartattache/category/categoryname/class/classname");
	
	 
		
		service = new CodedControlService();
		 List<CodedControlData> expectedCodeControlInsts = new ArrayList<CodedControlData>();
			
		 CodedControlData codedControlData = new CodedControlData();
		    codedControlData.setUuid("1ER-TUER-MISS-STEEL");
			codedControlData.setControlName("MPNFetch Test");
			codedControlData.setCreatedBy("MPNAdmin");
			Date dt = new Date();
			codedControlData.setDateCreated(dt);
			codedControlData.setDescription("MPNAdmin Fetch test");
			codedControlData.setValid(true);
			
			 Category category = new Category();
			 category.setId(1);
			 category.setCategoryName("MPN Category Test");
			 category.setValid(true);
			 
			 codedControlData.setCategory(category);
			 
			 Classification classif = new Classification();
			 classif.setId(1);
			 classif.setClassName("MPN Classification Test");
			 classif.setValid(true);
			 
			 codedControlData.setClassification(classif);
			 
			 expectedCodeControlInsts.add(codedControlData);
		
		expect(codedControlDataDAO.findCodedControlDataWithControlName("MPN")).andReturn(expectedCodeControlInsts);
		replay(codedControlDataDAO);
		
		ReflectionTestUtils.setField(service, "codedControlDataDAO", codedControlDataDAO);
		
		UserResponse resp = service.fetchControl("codedcontrolservice/control/name/MPN");
		resp.getMessage();
		assertEquals("Classfication Name","MPNFetch Test",resp.getCodedControls().get(0).getControlName());
		

	}	
	
	
	/**
	 * Test create control.
	 */
	@Test
	public void testCreateControl() {
	WebClient client = WebClient.create(ENDPOINT_ADDRESS);
	WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
	
	service = new CodedControlService();
	 List<CodedControlData> expectedCodeControlInsts = new ArrayList<CodedControlData>();
		
	 CodedControlData codedControlData = new CodedControlData();
	    codedControlData.setUuid("1ER-TUER-MISS-STEEL");
		codedControlData.setControlName("MPNFetch Test");
		codedControlData.setCreatedBy("MPNAdmin");
		Date dt = new Date();
		codedControlData.setDateCreated(dt);
		codedControlData.setDescription("MPNAdmin Fetch test");
		codedControlData.setValid(true);
		
		 Category category = new Category();
		 category.setId(1);
		 category.setCategoryName("MPN Category Test");
		 category.setValid(true);
		 
		 codedControlData.setCategory(category);
		 
		 Classification classif = new Classification();
		 classif.setId(1);
		 classif.setClassName("MPN Classification Test");
		 classif.setValid(true);
		 
		 codedControlData.setClassification(classif);
		 
		 expectedCodeControlInsts.add(codedControlData);
	
/*		 expect(codedControlDataDAO.persist(codedControlData)).andReturn(null);
		 	replay(codedControlDataDAO);

	      
	      
//	      service.createControl(codedControlData);
		 codedControlDataDAO.persist(EasyMock.createMock(CodedControlData.class));
	      expectLastCall();
	      replay(codedControlDataDAO);
	      ReflectionTestUtils.setField(service, "codedControlDataDAO", codedControlDataDAO);
	      
	      service.createControl(codedControlData);
*/

	
	
	}		
	
	
	/**
	 * Test fetch categories.
	 */
	@Test
	public void testFetchCategories() {

		service = new CodedControlService();
				
		 List<Category> expectedCategoryInsts = new ArrayList<Category>();
		
		 Category category = new Category();
		 category.setId(1);
		 category.setCategoryName("MPN Category Test");
		 category.setValid(true);
		 expectedCategoryInsts.add(category);
		
		expect(categoryDAO.findAllCategoriesSorted()).andReturn(expectedCategoryInsts);
		replay(categoryDAO);
		
		ReflectionTestUtils.setField(service, "categoryDAO", categoryDAO);
		
		UserResponse resp = service.fetchCategories();
		resp.getMessage();
		assertEquals("Classfication Name","MPN Category Test",resp.getCodedControls().get(0).getCategory().getCategoryName());
	}		
	
	/**
	 * Test fetch categories.
	 */
	@Test
	public void testFetchClasses() {

		service = new CodedControlService();
				
		 List<gov.va.med.mpn.entity.pojo.Classification> expectedClassInsts = new ArrayList<gov.va.med.mpn.entity.pojo.Classification>();
		
		 gov.va.med.mpn.entity.pojo.Classification classif = new gov.va.med.mpn.entity.pojo.Classification();
		 classif.setId(1);
		 classif.setClassName("MPN Classification Test");
		 classif.setValid(true);
		 expectedClassInsts.add(classif);
		
		expect(classificationDao.findAllClassesSorted()).andReturn(expectedClassInsts);
		replay(classificationDao);
		
		ReflectionTestUtils.setField(service, "classificationDao", classificationDao);
		
		UserResponse resp = service.fetchClasses();
		resp.getMessage();
		assertEquals("Classfication Name","MPN Classification Test",resp.getCodedControls().get(0).getClassification().getClassName());
		  
	}		
	
}
