package itn.let.mjo.test.web;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

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

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import itn.com.cmm.EgovMessageSource;
import itn.com.cmm.LoginVO;
import itn.com.cmm.service.EgovFileMngUtil;
import itn.let.mjo.payva.service.VacsVactService;
import itn.let.mjo.payva.service.VacsVactVO;
import itn.let.uss.umt.service.EgovUserManageService;
import itn.let.utl.user.service.CheckFileUtil;
import itn.let.utl.user.service.CheckLoginUtil;

@Controller
public class TestCrawlerController {
	
	//로그인 처리
	@Resource(name = "checkLoginUtil")
	private CheckLoginUtil checkLoginUtil;
	
    //첨부파일 체크
	@Resource(name = "checkFileUtil")
	private CheckFileUtil checkFileUtil;
	
	//가상계좌원장
    @Resource(name="vacsVactService")
    private VacsVactService vacsVactService;

	//파일 체크 & 관리
    @Resource(name="EgovFileMngUtil")
	private EgovFileMngUtil egovFileMngUtil;
    
	/** EgovMessageSource */
    @Resource(name="egovMessageSource")
    EgovMessageSource egovMessageSource;
    
	/** userManageService */
	@Resource(name = "userManageService")
	private EgovUserManageService userManageService;
	
	/*

    
    //파일 정보 관리
    @Resource(name="EgovFileMngService")
    private EgovFileMngService fileMngService;
    */
    
	
    private static final Logger logger = LoggerFactory.getLogger(TestController.class);
    
    /////////////////////////////////////////////////////////////////////////////////////////
    //
    //
    //	USER
    //
    //
    
    
    /////////////////////////////////////////////////////////////////////////////////////////
    //
    //
    //	ADMIN
    //
    //
    
    /**
     * egov sample list 페이지
     * @param addrVO
     * @param model
     * @return
     * @throws Exception
     */
        
    @RequestMapping(value= {
    		"/uss/ion/test/TestCrawlerList.do"
			})    
    public String selectTestList(
    		HttpServletRequest request
    		, @ModelAttribute("searchVO") VacsVactVO vacsVactVO
    		, ModelMap model
    		, RedirectAttributes redirectAttributes
    		) throws Exception {

    	
    	//관리자 로그인 여부 체크
    	String isLogin = checkLoginUtil.isAdminLogin4PageMove(redirectAttributes);    	
    	if (!"Y".equals(isLogin)) return isLogin;
    	
    	
    	//로그인 정보 획득
    	LoginVO loginVO = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
    	
    	
    	//login 정보
    	model.addAttribute("loginVO", loginVO);
    	
    	
    	//ajax를 위한 현재 URL 정보 받기
    	vacsVactVO.setUrl(request.getRequestURI()); 
		return "/uss/ion/test/TestCrawlerList";    	
    	
    }    
    

    /**
	 *egov file 업로드시 사용자 제약 관리 페이지
	 *
	 * @param boardVO
	 * @param board
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= 
		{		
				"/uss/ion/test/insertTestCrawlerAjax.do"
				}
	)
	public void insertTestFileList(
			HttpServletRequest request
			, HttpServletResponse response
			//, final MultipartHttpServletRequest multiRequest
			//, ModelMap model
			, ModelAndView modelAndView
			, RedirectAttributes redirectAttributes			 
			) throws Exception {

		String p_url	=	request.getParameter("url");
		
		String p_page_start	=	request.getParameter("page_start");
		String p_page_end	=	request.getParameter("page_end");
		
		int i_start	=	Integer.parseInt(p_page_start);
		int i_end	=	Integer.parseInt(p_page_end);
		
		
		String p_param0	=	request.getParameter("param0");
		String p_param1	=	request.getParameter("param1");
		String p_param2	=	request.getParameter("param2");
		String p_param3	=	request.getParameter("param3");
		String p_param4	=	request.getParameter("param4");
		String p_param5	=	request.getParameter("param5");
		
		String p_pre_detailPage	=	request.getParameter("pre_detailPage");
		String p_detailPage	=	request.getParameter("detailPage");
		String p_detailPageAttr	=	request.getParameter("detailPageAttr");
		
		String p_target1	=	request.getParameter("target1");
		String p_target2	=	request.getParameter("target2");
		String p_target3	=	request.getParameter("target3");
		String p_target4	=	request.getParameter("target4");
		String p_target5	=	request.getParameter("target5");
		String p_target6	=	request.getParameter("target6");
		String p_target7	=	request.getParameter("target7");
		String p_target8	=	request.getParameter("target8");
		String p_target9	=	request.getParameter("target9");
		String p_target10	=	request.getParameter("target10");

		String p_target1attr	=	request.getParameter("target1attr");
		String p_target2attr	=	request.getParameter("target2attr");
		String p_target3attr	=	request.getParameter("target3attr");
		String p_target4attr	=	request.getParameter("target4attr");
		String p_target5attr	=	request.getParameter("target5attr");
		String p_target6attr	=	request.getParameter("target6attr");
		String p_target7attr	=	request.getParameter("target7attr");
		String p_target8attr	=	request.getParameter("target8attr");
		String p_target9attr	=	request.getParameter("target9attr");
		String p_target10attr	=	request.getParameter("target10attr");
		
		//상세 url 가져오기
		List<String> l_infoUrl 	= new ArrayList<String>();
		
		List<String> l_target1	= new ArrayList<String>();
		List<String> l_target2	= new ArrayList<String>();
		List<String> l_target3	= new ArrayList<String>();
		List<String> l_target4	= new ArrayList<String>();
		List<String> l_target5	= new ArrayList<String>();
		List<String> l_target6	= new ArrayList<String>();
		List<String> l_target7	= new ArrayList<String>();
		List<String> l_target8	= new ArrayList<String>();
		List<String> l_target9	= new ArrayList<String>();
		List<String> l_target10	= new ArrayList<String>();
		
		{
			String s_url	=	p_url+"?";
			Document doc = null;        //Document에는 페이지의 전체 소스가 저장된다
			
			
			
			
			if (!"".equals(p_param1)) s_url	=	s_url	+	p_param1 + "&";
			if (!"".equals(p_param2)) s_url	=	s_url	+	p_param2 + "&";
			if (!"".equals(p_param3)) s_url	=	s_url	+	p_param3 + "&";
			if (!"".equals(p_param4)) s_url	=	s_url	+	p_param4 + "&";
			if (!"".equals(p_param5)) s_url	=	s_url	+	p_param5 + "&";
			
			
			
			for (int i=i_start;i<=i_end;i++) {
				String s_in_url	=	"";
				
				if (!"".equals(p_param0)) s_in_url	=	s_url	+	p_param0 + "="	+	Integer.toString(i);
				
				//2.페이지 호출
				doc = Jsoup.connect(s_in_url).get();
				
				//3.상세 url 추출
				Elements element = doc.select(p_detailPage);
				
				for (int j=0;j<element.size();j++) {
					//attr 값이 있으면 attr로 추출하고 아니면 text 값을 추출한다.
					if (!"".equals(p_detailPageAttr))	l_infoUrl.add(p_pre_detailPage + element.get(j).attr(p_detailPageAttr));
					else l_infoUrl.add(p_pre_detailPage + element.get(j).text());
					
				}
			}	
		}
		
		//데이터 추출
		{
			Document doc = null;        //Document에는 페이지의 전체 소스가 저장된다
			
			for (int i=0;i<l_infoUrl.size();i++) {
				
				//System.out.println("extract");
				System.out.println(i);
								
				doc = Jsoup.connect(l_infoUrl.get(i)).get();
				
				//상세 페이지 호출 및 데이터 추출
				if (!"".equals(p_target1)) this.extractData(doc, p_target1, p_target1attr, l_target1);				
				if (!"".equals(p_target2)) this.extractData(doc, p_target2, p_target2attr, l_target2);				
				if (!"".equals(p_target3)) this.extractData(doc, p_target3, p_target3attr, l_target3);
				if (!"".equals(p_target4)) this.extractData(doc, p_target4, p_target4attr, l_target4);
				if (!"".equals(p_target5)) this.extractData(doc, p_target5, p_target5attr, l_target5);
				if (!"".equals(p_target6)) this.extractData(doc, p_target6, p_target6attr, l_target6);
				if (!"".equals(p_target7)) this.extractData(doc, p_target7, p_target7attr, l_target7);
				if (!"".equals(p_target8)) this.extractData(doc, p_target8, p_target8attr, l_target8);
				if (!"".equals(p_target9)) this.extractData(doc, p_target9, p_target9attr, l_target9);
				if (!"".equals(p_target10)) this.extractData(doc, p_target10, p_target10attr, l_target10);
						
			}
		}
		
		//excel 생성
		{
			/*
			System.out.println("url");
			for (int i=0;i<l_infoUrl.size();i++) {
				System.out.println(l_infoUrl.get(i));
			}
			
			System.out.println("1");
			for (int i=0;i<l_target1.size();i++) {
				System.out.println(l_target1.get(i));
			}
			
			System.out.println("12");
			for (int i=0;i<l_target2.size();i++) {
				System.out.println(l_target2.get(i));
			}
			
			System.out.println("13");
			for (int i=0;i<l_target3.size();i++) {
				System.out.println(l_target3.get(i));
			}
			
			System.out.println("14");
			for (int i=0;i<l_target4.size();i++) {
				System.out.println(l_target4.get(i));
			}
			*/
			
	  		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
	  		SXSSFWorkbook wb = new SXSSFWorkbook(100);
	  		CellStyle style = wb.createCellStyle();
	  		style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
	   		style.setBorderLeft(CellStyle.BORDER_THIN);
	   		style.setBorderRight(CellStyle.BORDER_THIN);
	   		style.setBorderTop(CellStyle.BORDER_THIN);
	   		Font font = wb.createFont();
	   		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
	   		
	   		
	  		Cell cell = null;
	  		Row row = null;
	  		
	  		
	  		
	  		
	  		String sheetTitle = "";
	  		String fileName ="관리자 리스트";
	  		try{
	  			sheetTitle = "관리자 리스트(화면)" ; //제목

  				Sheet sheet = wb.createSheet(sheetTitle);
  				row = sheet.createRow(0);
  				
  				//타이틀 만들기
  				/*
  		        for(int i=0 ; i < userExcelValue.length ; i++) {
	  	 		       cell = row.createCell(i);
	  	 		       cell.setCellStyle(style);
	  		 	       cell.setCellValue(userExcelValue[i][1]);
  		        }
  		        */
	  	 		   
  				
  		        //내용 만들기
  				int i_cell_size =	0;
  				  						
  		        for(int i=0; i < l_infoUrl.size(); i++){
  			    	row = sheet.createRow(i);
  			    	
  			    	i_cell_size =	0;
  			    	
  			    	this.makeExcelData(i_cell_size++, row, style, l_infoUrl.get(i));
  			    	
  			    	if (l_infoUrl.size()==l_target1.size()) {
  			    		this.makeExcelData(i_cell_size++, row, style, l_target1.get(i));
  			    		/*
  			    		cell = row.createCell(i_cell_size++);
  			    		cell.setCellStyle(style);
  			    		cell.setCellValue(l_target1.get(i)); //번호
  			    		*/
  			    	}
  			    	
  			    	if (l_infoUrl.size()==l_target2.size()) this.makeExcelData(i_cell_size++, row, style, l_target2.get(i));
  			    	if (l_infoUrl.size()==l_target3.size()) this.makeExcelData(i_cell_size++, row, style, l_target3.get(i));
  			    	if (l_infoUrl.size()==l_target4.size()) this.makeExcelData(i_cell_size++, row, style, l_target4.get(i));
  			    	if (l_infoUrl.size()==l_target5.size()) this.makeExcelData(i_cell_size++, row, style, l_target5.get(i));
  			    	if (l_infoUrl.size()==l_target6.size()) this.makeExcelData(i_cell_size++, row, style, l_target6.get(i));
  			    	if (l_infoUrl.size()==l_target7.size()) this.makeExcelData(i_cell_size++, row, style, l_target7.get(i));
  			    	if (l_infoUrl.size()==l_target8.size()) this.makeExcelData(i_cell_size++, row, style, l_target8.get(i));
  			    	if (l_infoUrl.size()==l_target9.size()) this.makeExcelData(i_cell_size++, row, style, l_target9.get(i));
  			    	if (l_infoUrl.size()==l_target10.size()) this.makeExcelData(i_cell_size++, row, style, l_target10.get(i));
  			    	
  		        }  		        
	  	    response.setHeader("Set-Cookie", "fileDownload=true; path=/");
	  		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", Locale.KOREA );
	  		Date currentTime = new Date ();
	  		String mTime = mSimpleDateFormat.format ( currentTime );
	  		fileName = fileName+"("+mTime+")";
	  		
	  		response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
	  		wb.write(response.getOutputStream());
	  	    
	  		}catch(Exception e) {
	  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
	  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
	  			response.setHeader("Content-Type","text/html; charset=utf-8");
	  			OutputStream out = null;
	  			try {
	  				out = response.getOutputStream();
	  				byte[] data = new String("fail..").getBytes();
	  				out.write(data, 0, data.length);
	  			} catch(Exception ignore) {
	  				ignore.printStackTrace();
	  			} finally {
	  				if(out != null) try { out.close(); } catch(Exception ignore) {}
	  			}
	  		}finally {
	  			// 디스크 적었던 임시파일을 제거합니다.
	  			wb.dispose();
	  			try { wb.close(); } catch(Exception ignore) {}
	  		}
	  		
	  		
	  		
				
		}
		
		/*
		//json 알림
		modelAndView.setViewName("jsonView");
				
		
    	//사용자 로그인 여부 체크 for json
    	String isLogin = checkLoginUtil.isLoginCheck4JsonAction(modelAndView);    	
    	if ("N".equals(isLogin)) return modelAndView;	
    	

    	
    	
		//if ("ERROR".equals(atchFileIds[0])) return modelAndView;
		
		System.out.println("success");
		
		return modelAndView;
		*/
	}

	/////////////////////////////////////////////////////////
	//
	//	private
	//
	//
	
	private List<String> extractData(
			Document p_doc			
			, String p_target1
			, String p_target1attr
			, List<String> l_target1
			) throws Exception{
		
		//Document doc = null;        //Document에는 페이지의 전체 소스가 저장된다
		//doc = Jsoup.connect(p_call_url).get();
		
		//System.out.println(p_call_url);
		
		
		//attr 값이 있으면 attr로 추출하고 아니면 text 값을 추출한다.
		if (!"".equals(p_target1attr)) l_target1.add(p_doc.select(p_target1).get(0).attr(p_target1attr));
		else l_target1.add(p_doc.select(p_target1).get(0).text());
		
		
		
		return l_target1;
		
		
	}
	
	private void makeExcelData(
			int i_cell_size
			, Row p_row
			, CellStyle p_style
			, String p_val
			) throws Exception{		
		Cell cell = p_row.createCell(i_cell_size++);
		cell.setCellStyle(p_style);
		cell.setCellValue(p_val); //번호
	}
}
