package kcg.faics.cmmn.service.impl;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

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 org.springframework.test.context.web.WebAppConfiguration;

import kcg.faics.cmmn.service.CodeService;
import kcg.faics.cmmn.vo.CodeVO;

/**
 * CodeServiceImpl 테스트 클래스.
 * 
 * @author kimnomin
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "classpath:/spring/context-*.xml" })
public class CodeServiceImplTest {
	/**
	 * 코드 관련 서비스 객체.
	 */
	@Autowired
	private CodeService codeService;

	/**
	 * getCodeValue 메소드 테스트.
	 * 
	 * <pre>
	 * CASE 1. code1 = 'C001' AND code2 = 'PS91' 이면 반환되는 레코드의 CODENM은 제주지방해양경비안전본부여야 한다.
	 * CASE 2. code1 = 'C001' AND code2 = null 이면 반환되는 레코드의 CODENM은 Order by 규칙에 의한 정렬 값의 
	 * 			첫번째 값인 해양경비안전본부여야 한다.
	 * </pre>
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@Test
	public void getCodeValue() throws Exception {
		String okCase1 = "제주지방해양경비안전본부";
		String okCase2 = "해양경비안전본부";
		CodeVO code;
		
		// Case 1
		code = codeService.getCodeValue("C001", "PS91");
		assertEquals(okCase1, code.getCodenm());
		
		// Case 2
		code = codeService.getCodeValue("C001", null);
		assertEquals(okCase2, code.getCodenm());
	}

	/**
	 * getPlace1List 메소드 테스트.
	 * 
	 * <pre>
	 * CASE 1. onlyCentral 값이 true 이면 반환되는 레코드 개수가 24개여야 한다. 
	 * CASE 2. onlyCentral 값이 false 이면 반환되는 레코드 개수가 29개여야 한다.
	 * => 해당 테스트 케이스는 2016-10-21일 Test Database에 있는 레코드를 기준으로 한다.
	 * </pre>
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@Test
	public void getPlace1ListTest() throws Exception {
		int okCase1 = 24;
		int okCase2 = 29;
		List<CodeVO> codes;

		// Case 1
		codes = codeService.getPlace1List(true);
		assertEquals(okCase1, codes.size());

		// Case 2
		codes = codeService.getPlace1List(false);
		assertEquals(okCase2, codes.size());
	}
	
	/**
	 *  getPlace1SubList 메소드 테스트.
	 *  
	 *  <pre>
	 *  상하위 구조는 불행히도 하드코딩되어있다. (CodeService.PLACE_CATEGORY)
	 *  
	 *  CASE. CodeService.PLACE_CATEGORY의 Key로 getPlace1SubList 함수를 실행시킨 결과와 
	 *  		Value에 있는 배열의 크기, 코드가 동일해야 한다.
	 *  </pre>
	 * @throws Exception
	 *             기본 예외 처리 
	 */
	@Test
	public void getPlace1SubListTest() throws Exception {
		String placeCode = "";
		List<CodeVO> codes = null;
		boolean isExist = false;
		
		for (Map.Entry<String, String[]> entry : CodeService.PLACE_CATEGORY.entrySet()) {
		    String key = entry.getKey();
		    String[] value = entry.getValue();

		    placeCode = key;
			codes = codeService.getPlace1SubList(placeCode);
			for (CodeVO code : codes) {
				isExist = false;
				isExist = Arrays.asList(value).contains(code.getCode2());
				assertEquals(true, isExist);
			}
			assertEquals(value.length, codes.size());
		}
	}
	
	/**
	 * getPlace1List(String[]) 메서드 테스트.
	 * 
	 * <pre>
	 * CASE 1. 해양경비안전서 코드 목록을 기준으로 List를 추출하면 input갯수와 output갯수가 같아야 한다.
	 * </pre>
	 * @throws Exception
	 *             기본 예외 처리 
	 */
	@Test
	public void getPlace1ListTest2() throws Exception {
		List<CodeVO> codes = codeService.getPlace1List(CodeService.POLICE_STATION_LIST);
		assertEquals(CodeService.POLICE_STATION_LIST.length, codes.size());
	}
	
	/**
	 * getCoprOrgList 메서드 테스트.
	 * 
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@Test
	public void getCoprOrgListTest() throws Exception {
		List<CodeVO> codes = codeService.getCorpOrgList();
		assertEquals(11, codes.size());
	}
}
