
package nlib.bbs.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import nlib.bbs.service.BoardServiceApi;
import nlib.cmm.NlibCommonController;
import nlib.cmm.crypto.AriaCrypto;
import nlib.cmm.crypto.NlibPasswordEncoder;
import nlib.cmm.service.CodeService;
import nlib.cmm.service.NlibProperty;
import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;

@Controller
public class BoardControllerApi extends NlibCommonController
{
	private static final Logger log = LoggerFactory.getLogger(BoardControllerApi.class);
	
	static final String DEFUALT_PAGE_SIZE = NlibProperty.getProperty("list.paging.page.size");
	
	@Resource(name = "boardService")
	private BoardServiceApi boardService;
	
	@Resource(name = "nlibPasswordEncoder")
	private NlibPasswordEncoder nlibPasswordEncoder;
	
	@Resource(name = "ariaCrypto")
	private AriaCrypto ariaCrypto;
	
	@Resource(name = "codeService") 
	private CodeService codeService;
	

	@Autowired
	private AuthenticationManager authenticationManager;

	/**
	 * 공지사항 목록 화면을 표출한다. 
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/listNotices.do")
	public String listNotices(HttpServletRequest req, Authentication authentication, @RequestParam Map<String, String> paramMap, ModelMap model) throws Exception  {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		String articleType = paramMap.get("articleType");
		String message = paramMap.get("message");

		log.debug("listNotices > pageIndex = " + pageIndex);
		log.debug("listNotices > pageSize = " + pageSize);
		log.debug("listNotices > searchKeyword = " + searchKeyword);
		log.debug("listNotices > articleType = " + articleType);
		log.debug("listNotices > message = " + message);

		// 페이징 사이즈 코드 목록 조회 
		List<HashMap<String,String>> pageSizeCodes = codeService.listCodes("PAGE_SIZE_OPTION");
		
		// 공지사항 유형 코드 목록 조회 
		List<HashMap<String,String>> articleTypeCodes = codeService.listCodes("ARTICLE_TYPE");
		
		// 반환 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);
    	model.addAttribute("pageSizeCodes", pageSizeCodes);
    	model.addAttribute("articleTypeCodes", articleTypeCodes);
    	model.addAttribute("articleType"  , articleType);
    	model.addAttribute("message"      , message);
    	
		return "nlib/board/listNotices";
	}

	/**
	 * 공지사항 목록 조회한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(value="/board/listNoticesAjax.do")
	public ResponseEntity<String> listNoticesAjax(HttpServletRequest req, 
			Authentication authentication, @RequestBody Map<String, String> paramMap) throws Exception {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		String articleType = paramMap.get("articleType");
		
		log.debug("listNoticesAjax > pageIndex = " + pageIndex);
		log.debug("listNoticesAjax > pageSize = " + pageSize);
		log.debug("listNoticesAjax > searchKeyword = " + searchKeyword);
		log.debug("listNoticesAjax > articleType = " + articleType);
		
		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("searchKeyword", searchKeyword);
    	reqVO.putInfoItem("articleType", articleType);

    	// 요청 
    	DataApiResVO resVO = boardService.listNotices(reqVO);
    	
		//-------------------------------
		// JSON변환 응답 처리
		//-------------------------------
    	// JS-GRID 페이징 처리를 포함한 응답값 처리
    	// {data: [{...}], 
    	//  itemsCount: 255
    	// }
    	HashMap<String, Object> retMap = new HashMap<String, Object>();
    	retMap.put("data", resVO.getList("record"));
    	retMap.put("itemsCount", resVO.getRecordTotCount());
    	
    	return makeResponseEntityJson(retMap);
	}

	/**
	 * 공지사항 상세 내용 조회한다.
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/selectNotice.do")
	public String selectNotice(HttpServletRequest req, Authentication authentication, @RequestParam Map<String, String> paramMap, ModelMap model) throws Exception {

		// 목록 이동시 전달할 매개변수 
		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = paramMap.get("pageIndex");
		String pageSize = paramMap.get("pageSize");
		String articleType = paramMap.get("articleType");
		String message = paramMap.get("message");
		
		// 게시물 번호 
		String articleNo = paramMap.get("articleNo");
		
		log.debug("selectNotice > pageIndex = " + pageIndex);
		log.debug("selectNotice > pageSize = " + pageSize);
		log.debug("selectNotice > searchKeyword = " + searchKeyword);
		log.debug("selectNotice > articleNo = " + articleNo);
		log.debug("selectNotice > message = " + message);
		log.debug("selectNotice > articleType = " + articleType);

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("boardNo", "QNA");       // 게시판ID
    	reqVO.putInfoItem("articleNo", articleNo); // 게시물번호

    	// 요청 
    	DataApiResVO resVO = boardService.selectNotice(reqVO);
    	
    	// 반환 정보 
    	model.addAttribute("articleNo"    , articleNo);
    	model.addAttribute("article"      , resVO.getInfo()); // 게시물 상세 
    	model.addAttribute("preArticle"   , resVO.getList("record").get(0)); // 이전글 정보
    	model.addAttribute("nextArticle"  , resVO.getList("record").get(1)); // 다음글 정보
    	model.addAttribute("message"      , message);
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);
    	model.addAttribute("articleType"  , articleType);
    	
		return "nlib/board/selectNotice";
	}

	/**
	 * FAQ 목록 화면을 표출한다. 
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/listFAQs.do")
	public String listFAQs(HttpServletRequest req, Authentication authentication, @RequestParam Map<String, String> paramMap, ModelMap model) throws Exception {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		String message = paramMap.get("message");
		String faqType = paramMap.get("faqType");
		
		log.debug("listFAQs > pageIndex = " + pageIndex);
		log.debug("listFAQs > pageSize = " + pageSize);
		log.debug("listFAQs > searchKeyword = " + searchKeyword);
		log.debug("listFAQs > message = " + message);
		log.debug("listFAQs > faqType = " + faqType);

		DataApiReqVO reqVOforCode = new DataApiReqVO();
		reqVOforCode.setPageIndex(0);
		reqVOforCode.setPageSize(0);
		

		// 페이징 사이즈 코드 목록 조회 
		List<HashMap<String,String>> pageSizeCodes = codeService.listCodes("PAGE_SIZE_OPTION");
		
		// 유형 코드 목록 조회 
		List<HashMap<String,String>> articleTypeCodes = codeService.listCodes("FAQ_TYPE");
		
		// 반환 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);
    	model.addAttribute("pageSizeCodes", pageSizeCodes);
    	model.addAttribute("faqTypeCodes" , articleTypeCodes);
    	model.addAttribute("message"      , message);
    	model.addAttribute("faqType"      , faqType);
    	model.addAttribute("faqType"      , faqType);
    	
		return "nlib/board/listFAQs";
	}


	/**
	 * FAQ 목록 조회한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(value="/board/listFAQsAjax.do")
	public ResponseEntity<String> listFAQsAjax(HttpServletRequest req, 
			Authentication authentication, @RequestBody Map<String, String> paramMap) throws Exception {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		String faqType = paramMap.get("faqType");
		
		log.debug("listFAQsAjax > pageIndex = " + pageIndex);
		log.debug("listFAQsAjax > pageSize = " + pageSize);
		log.debug("listFAQsAjax > searchKeyword = " + searchKeyword);
		log.debug("listFAQsAjax > faqType = " + faqType);

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("searchKeyword", searchKeyword);
    	reqVO.putInfoItem("faqType", faqType);

    	// 요청 
    	DataApiResVO resVO = boardService.listFAQs(reqVO);
    	
		//-------------------------------
		// JSON변환 응답 처리
		//-------------------------------
    	// JS-GRID 페이징 처리를 포함한 응답값 처리
    	// {data: [{...}], 
    	//  itemsCount: 255
    	// }
    	HashMap<String, Object> retMap = new HashMap<String, Object>();
    	retMap.put("data", resVO.getList("record"));
    	retMap.put("itemsCount", resVO.getRecordTotCount());
    	
    	return makeResponseEntityJson(retMap);
	}
	

	/**
	 * 묻고답하기 상세 내용 조회한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/selectFAQAjax.do")
	public ResponseEntity<String> selectFAQAjax(HttpServletRequest req, Authentication authentication, @RequestBody Map<String, String> paramMap) throws Exception {

		// 게시물 번호
		String articleNo = paramMap.get("articleNo");
		
		log.debug("selectQnA > articleNo = " + articleNo);

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.putInfoItem("boardNo", "FAQ");       // 게시판ID
    	reqVO.putInfoItem("articleNo", articleNo); // 게시물번호

    	// 요청 
    	DataApiResVO resVO = boardService.selectFAQ(reqVO);
    	
    	// 반환 정보 
    	return makeResponseEntityJson(resVO);
	}

	/**
	 * 묻고답하기 목록 화면을 표출한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/listQnAs.do")
	public String listQnAs(HttpServletRequest req, Authentication authentication, @RequestParam Map<String, String> paramMap, ModelMap model) throws Exception {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		String message = paramMap.get("message");

		log.debug("listQnAs > pageIndex = " + pageIndex);
		log.debug("listQnAs > pageSize = " + pageSize);
		log.debug("listQnAs > searchKeyword = " + searchKeyword);
		log.debug("listQnAs > message = " + message);

		// 페이징 사이즈 코드 목록 조회 
		List<HashMap<String,String>> pageSizeCodes = codeService.listCodes("PAGE_SIZE_OPTION");
		
		// 반환 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);
    	model.addAttribute("pageSizeCodes", pageSizeCodes);
    	model.addAttribute("message"      , message);
    	
		return "nlib/board/listQnAs";
	}

	/**
	 * 묻고답하기 목록 조회한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(value="/board/listQnAsAjax.do")
	public ResponseEntity<String> listQnAsAjax(HttpServletRequest req, 
			Authentication authentication, @RequestBody Map<String, String> paramMap) throws Exception {

		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = StringUtil.getString(paramMap.get("pageIndex"), "1");
		String pageSize  = StringUtil.getString(paramMap.get("pageSize") , DEFUALT_PAGE_SIZE);
		
		log.debug("listQnAsAjax > pageIndex = " + pageIndex);
		log.debug("listQnAsAjax > pageSize = " + pageSize);
		log.debug("listQnAsAjax > searchKeyword = " + searchKeyword);

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("searchKeyword", searchKeyword);

    	// 요청 
    	DataApiResVO resVO = boardService.listQnAs(reqVO);
    	
		//-------------------------------
		// JSON변환 응답 처리
		//-------------------------------
    	// JS-GRID 페이징 처리를 포함한 응답값 처리
    	// {data: [{...}], 
    	//  itemsCount: 255
    	// }
    	HashMap<String, Object> retMap = new HashMap<String, Object>();
    	retMap.put("data", resVO.getList("record"));
    	retMap.put("itemsCount", resVO.getRecordTotCount());
    	
    	return makeResponseEntityJson(retMap);
	}

	
	/**
	 * 묻고답하기 상세 내용 조회한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/selectQnA.do")
	public String selectQnA(HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, ModelMap model) throws Exception {
		
		addParamFromInputFlash(paramMap, req);

		// 목록 이동시 전달할 매개변수 
		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = paramMap.get("pageIndex");
		String pageSize = paramMap.get("pageSize");
		String message = paramMap.get("message");
		
		// 게시물 번호 
		String articleNo = paramMap.get("articleNo");
		
		log.debug("selectQnA > pageIndex = " + pageIndex);
		log.debug("selectQnA > pageSize = " + pageSize);
		log.debug("selectQnA > searchKeyword = " + searchKeyword);
		log.debug("selectQnA > articleNo = " + articleNo);
		log.debug("selectQnA > message = " + message);

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("boardNo", "QNA");       // 게시판ID
    	reqVO.putInfoItem("articleNo", articleNo); // 게시물번호

    	// 요청 
    	DataApiResVO resVO = boardService.selectQnA(reqVO);
    	
    	// 반환 정보 
    	model.addAttribute("articleNo"    , articleNo);
    	model.addAttribute("article"      , resVO.getInfo()); // 게시물 상세 
    	model.addAttribute("preArticle"   , resVO.getList("record").get(0)); // 이전글 정보
    	model.addAttribute("nextArticle"  , resVO.getList("record").get(1)); // 다음글 정보
    	model.addAttribute("message"      , message);
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);

		return "nlib/board/selectQnA";
	}

	/**
	 * 묻고답하기 글작성화면을 표출한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping("/board/insertQnAForm.do")
	public String insertQnAForm(HttpServletRequest req, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, ModelMap model) throws Exception {
		
		// 입력 매개변수 출력 설정 
    	addParamsToModel(paramMap, model); 

		NlibLoginVO loginVO = getNlibLoginVO(authentication);
		if(StringUtil.isEmpty(paramMap.get("regUserName"))) model.addAttribute("regUserName", loginVO.getName());
		if(StringUtil.isEmpty(paramMap.get("email"))) model.addAttribute("regUserName", loginVO.getEmail());

		return "nlib/board/insertQnAForm";
	}

	/**
	 * 묻고답하기 등록 처리한다. 
	 * 
	 * @param req
	 * @param authentication
	 * @param paramMap
	 * @param model
	 * @return
	 */
	@RequestMapping("/board/insertQnA.do")
	public String insertQnA(HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, RedirectAttributes redirectAttrs
			, ModelMap model) throws Exception {
		
		NlibLoginVO loginVO = getNlibLoginVO(authentication);

		log.debug("paramMap > " + paramMap);

		String message = null;
		
		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.putInfoItem("boardNo"     , "QNA");
    	reqVO.putInfoItem("title"       , paramMap.get("title"));
    	reqVO.putInfoItem("regUserName" , paramMap.get("regUserName"));
    	reqVO.putInfoItem("email"       , paramMap.get("email"));
    	reqVO.putInfoItem("contentQeust", paramMap.get("contentQeust"));
    	
    	String fileListJsonStr = paramMap.get("fileList");
    	if(fileListJsonStr.startsWith("\"")) fileListJsonStr = fileListJsonStr.substring(1);
    	if(fileListJsonStr.endsWith("\"")) fileListJsonStr = fileListJsonStr.substring(0, fileListJsonStr.length()-1);
    	fileListJsonStr = fileListJsonStr.replaceAll("\\\\", "");
    	
    	log.debug("fileList : " + fileListJsonStr);
    	
    	/*
    	ObjectMapper mapper = new ObjectMapper();
    	List<Map<String, Object>> fileList = null;
    	try {
    		fileList = mapper.readValue(fileListJsonStr, new TypeReference<List<Map<String, Object>>>() {
            });
    		
            for (Map<String, Object> map : fileList) {
                MapUtils.debugPrint(System.out, "map", map);
            }

		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	log.debug("fileMap =" + fileList);
    	*/
    	reqVO.putInfoItem("fileList", fileListJsonStr);

    	// 요청 
    	DataApiResVO resVO = boardService.insertQnA(reqVO);
    	
    	// 처리결과 확인
    	if(!resVO.isSuccess()) {
    		message = resVO.getResultMessage();
    		redirectAttrs.addFlashAttribute("message", message);
    		addParamsToRedirect(paramMap, redirectAttrs, null, "pageIndex,pageSize,searchKeyword");
    		addParamsToRedirect(paramMap, redirectAttrs, null, 
  				  "title,articlePassword,"
  				+ "regDate, regUserName, "
  				+ "email, contentQeust");
    		
    		return "redirect:/board/insertQnAForm.do";
    	}
    	
    	redirectAttrs.addFlashAttribute("pageSize", paramMap.get("pageSize"));
    	redirectAttrs.addFlashAttribute("message", "성공적으로 등록되었습니다.");
    	
		return "redirect:/board/listQnAs.do";
	}

	@RequestMapping("/board/verifyWriter.do")
	public String verifyWriter(HttpServletRequest req) throws Exception {
		return "nlib/board/verifyWriter";
	}

	/**
	 * 묻고답하기 수정 화면 표출한다.
	 * 
	 * @param req
	 * @param authentication
	 * @param paramMap
	 * @param model
	 * @return
	 */
	@RequestMapping("/board/updateQnAForm.do")
	public String updateQnAForm(HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, ModelMap model
			, RedirectAttributes redirectAttrs
			) throws Exception {

		// 목록 이동시 전달할 매개변수 
		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = paramMap.get("pageIndex");
		String pageSize = paramMap.get("pageSize");
		
		// 게시물 번호 
		String articleNo = paramMap.get("articleNo");
		String articlePassword = paramMap.get("articlePassword");
		
		log.debug("updateQnAForm > pageIndex = " + pageIndex);
		log.debug("updateQnAForm > pageSize = " + pageSize);
		log.debug("updateQnAForm > searchKeyword = " + searchKeyword);
		log.debug("updateQnAForm > articleNo = " + articleNo);
		log.debug("updateQnAForm > articlePassword = " + articlePassword);
		
		if(StringUtil.isEmpty(articlePassword)) {
			redirectAttrs.addFlashAttribute("message", "비밀빈호가 올바르지 않습니다.(U1)");
			
			addParamsToRedirect(paramMap, redirectAttrs, null, "pageIndex,pageSize,searchKeyword,articleNo");
			return "redirect:/board/selectQnA.do";
		}

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("boardNo", "QNA"); // 게시판ID
    	reqVO.putInfoItem("articleNo", articleNo); // 게시물번호

    	// 요청 
    	DataApiResVO resVO = boardService.selectQnA(reqVO);
    	
    	// 비밀번호 확인 
    	HashMap<String, String> article = resVO.getInfo();
    	String shaArticlePassword = nlibPasswordEncoder.encode(articlePassword);
    	log.debug("updateQnAForm > 입력받은 비밀번호를 SHA256 암호화한 값 : " + shaArticlePassword);
    	
    	if(!shaArticlePassword.equals(article.get("articlePassword"))) {
    		redirectAttrs.addFlashAttribute("message", "비밀번호가 올바르지 않습니다.(U2)");
    		addParamsToRedirect(paramMap, redirectAttrs, null, "pageIndex,pageSize,searchKeyword,articleNo");
			return "redirect:/board/selectQnA.do";
    	}
    	
    	// 반환 정보 
    	model.addAttribute("articleNo"    , articleNo);
    	model.addAttribute("article"      , resVO.getInfo());
    	
		//-------------------------------
    	// 게시글 비밀번호 처리 
		//-------------------------------
    	// 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며, 
    	// 웹 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함
    	String encArticlePassword = StringUtil.encodeBase64(ariaCrypto.encode(shaArticlePassword));
    	model.addAttribute("encArticlePassword", encArticlePassword);
    	
    	// 검색 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);

		return "nlib/board/updateQnAForm";
	}
	
	/**
	 * 묻고답하기 수정 처리한다.
	 * 
	 * @param req
	 * @param authentication
	 * @param paramMap
	 * @param model
	 * @return
	 */
	@RequestMapping("/board/updateQnA.do")
	public String updateQnA(HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, RedirectAttributes redirectAttrs
			, ModelMap model) throws Exception {

		log.debug("paramMap > " + paramMap);

		String message = null;
		
		// 목록 이동시 전달할 매개변수 
		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = paramMap.get("pageIndex");
		String pageSize = paramMap.get("pageSize");
		
		// 게시물 번호
		String articleNo = paramMap.get("articleNo");
		
		//-------------------------------
    	// 게시글 비밀번호 처리 
		//-------------------------------
    	// 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며, 
    	// 웹 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함
		String encArticlePassword = paramMap.get("encArticlePassword");
		String checkArticlePassword = ariaCrypto.decode(StringUtil.decodeBase64(encArticlePassword));
		String articlePassword = paramMap.get("articlePassword");
		
		//-------------------------------
		// 비밀번호 유효 체크
		//-------------------------------
		// 기존 정보 조회 
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.putInfoItem("articleNo", articleNo);
    	
    	DataApiResVO resVO = boardService.selectQnA(reqVO);
    	String oldArticlePassword = resVO.getInfoItem("articlePassword");
    	if(checkArticlePassword == null || !checkArticlePassword.equals(oldArticlePassword)) {
    		redirectAttrs.addFlashAttribute("errorCode", "ERR_BRD_UPDTQNA");
    		redirectAttrs.addFlashAttribute("errorMessage", "잘못된 접근입니다.");
    		return "redirect:/alert/showError.do";
    	}

    	// 새 글비밀번호가 존재하지 않는 경우, 기존 비밀번호 설정 처리 
		if(StringUtil.isEmpty(articlePassword)) {
			articlePassword = checkArticlePassword;
		}
		// 새 글비밀번호가 입력된 경우, SHA256 암호화 처리하여 설정 
		else {
			articlePassword = nlibPasswordEncoder.encode(articlePassword);
		}
		
		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO updateReqVO = new DataApiReqVO();
    	updateReqVO.putInfoItem("boardNo"     , "QNA");
    	updateReqVO.putInfoItem("articleNo"   , articleNo);
    	updateReqVO.putInfoItem("title"       , paramMap.get("title"));
    	updateReqVO.putInfoItem("regUserName" , paramMap.get("regUserName"));
    	updateReqVO.putInfoItem("email"       , paramMap.get("email"));
    	updateReqVO.putInfoItem("contentQeust", paramMap.get("contentQeust"));
    	updateReqVO.putInfoItem("articlePassword", articlePassword); // SHA256 글비밀번호 
    	
    	// 요청 
    	DataApiResVO updateResVO = boardService.updateQnA(updateReqVO);
    	
    	// 처리결과 확인
    	if(!updateResVO.isSuccess()) {
    		message = updateResVO.getResultMessage();
    		model.addAttribute("message", message);
    		addParamsToModel(paramMap, model, null, "pageIndex,pageSize,searchKeyword,articleNo");
    		addParamsToModel(paramMap, model, "article"
    				, "articleNo,articleType,"
    				+ "articleTypeName,title,articlePassword,readCount,"
    				+ "regDate, reguserName,  repStats,   "
    				+ "email, contentQeust, "
    				+ "contentQuestFile");
    		
    		return "redirect:/board/updateQnAForm.do";
    	}
    	
    	// 반환 정보 
    	model.addAttribute("articleNo"    , updateResVO.getInfoItem("articleNo")); // 신규등록된 게시물 ID 
    	model.addAttribute("message"      , "성공적으로 수정되었습니다.");
    	
    	// 검색 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);

		return "redirect:/board/selectQnA.do";
	}
	
	/**
	 * 묻고답하기 삭제한다.
	 * 
	 * @param req
	 * @param authentication
	 * @param paramMap
	 * @param model
	 * @return
	 */
	@RequestMapping("/board/deleteQnA.do")
	public String deleteQnA(HttpServletRequest req, Authentication authentication, @RequestParam Map<String, String> paramMap, ModelMap model) throws Exception {

		String message = null;

		// 목록 이동시 전달할 매개변수 
		String searchKeyword = paramMap.get("searchKeyword");
		String pageIndex = paramMap.get("pageIndex");
		String pageSize = paramMap.get("pageSize");
		
		// 게시물 번호 
		String articleNo = paramMap.get("articleNo");
		String articlePassword = paramMap.get("articlePassword");
		
		log.debug("deleteQnA > pageIndex = " + pageIndex);
		log.debug("deleteQnA > pageSize = " + pageSize);
		log.debug("deleteQnA > searchKeyword = " + searchKeyword);
		log.debug("deleteQnA > articleNo = " + articleNo);
		log.debug("deleteQnA > articlePassword = " + articlePassword);
		
		if(StringUtil.isEmpty(articlePassword)) {
			model.addAttribute("message", "글비밀빈호가 올바르지 않습니다.(D1)");
			addParamsToModel(paramMap, model, null, "pageIndex,pageSize,searchKeyword,articleNo");
			return "redirect:/board/selectQnA.do";
		}

		//-------------------------------
		// REQ VO 구성 
		//-------------------------------
    	DataApiReqVO reqVO = new DataApiReqVO();
    	reqVO.setPageIndex(pageIndex);
    	reqVO.setPageSize(pageSize);
    	reqVO.putInfoItem("boardNo", "QNA"); // 게시판ID
    	reqVO.putInfoItem("articleNo", articleNo); // 게시물번호

    	// 요청 
    	DataApiResVO resVO = boardService.selectQnA(reqVO);
    	
    	// 비밀번호 확인 
    	HashMap<String, String> article = resVO.getInfo();
    	String shaArticlePassword = nlibPasswordEncoder.encode(articlePassword);
    	log.debug("updateQnAForm > 입력받은 비밀번호를 SHA256 암호화한 값 : " + shaArticlePassword);
    	
    	if(!shaArticlePassword.equals(article.get("articlePassword"))) {
			model.addAttribute("message", "글비밀번호가 올바르지 않습니다.(D2)");
			addParamsToModel(paramMap, model, null, "pageIndex,pageSize,searchKeyword,articleNo");
			return "redirect:/board/selectQnA.do";
    	}
    	
    	// 삭제 처리
    	DataApiResVO delResVO = boardService.deleteQnA(reqVO);

    	// 처리결과 확인
    	if(!delResVO.isSuccess()) {
    		message = delResVO.getResultMessage();
    		model.addAttribute("message", message);
    		addParamsToModel(paramMap, model, null, "pageIndex,pageSize,searchKeyword,articleNo");
    		
    		return "redirect:/board/selectQnA.do";
    	}
    	
    	// 반환 정보 
    	model.addAttribute("message"      , "성공적으로 삭제되었습니다.");
    	
    	// 검색 정보 
    	model.addAttribute("pageIndex"    , pageIndex);
    	model.addAttribute("pageSize"     , pageSize);
    	model.addAttribute("searchKeyword", searchKeyword);

		return "redirect:/board/listQnAs.do";
	}

}