package kr.co.kihyun.servlet;

import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import java.sql.Date;
import kr.co.kihyun.moumi.MoumiConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CustomBindingListener implements HttpSessionBindingListener {
    private static final Logger LOG = LoggerFactory.getLogger(CustomBindingListener.class);    
    private String num = null;
    private String ip = "";
    private String read_ip = null;// 현재 접속자 아이피

    public CustomBindingListener(String ip) {
        this.ip = ip;
    }

    public void valueBound(HttpSessionBindingEvent event) {
        // 세션이 생겼을 때 할 내용

        long t = System.currentTimeMillis();
        Date date = new Date(t);
        String chdate = date.toString();
        chdate = chdate.replace('-', '/');
        String today_count = null;
        String today = null;
        String today_num = null;// 오늘 방문자 카운트
        List<String> v = new ArrayList<String>();// 현재 접속자 아이피 체크

        //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Add by YOUNGJUN,CHO
        // finally 에서 close 하기 위해 try ~ catch 문 밖에 선언.
        FileReader fr = null;
        FileReader fr2 = null;
        FileReader fr3 = null;
        BufferedReader br = null;
        BufferedReader br2 = null;
        BufferedReader br3 = null;
        
        FileWriter fwTotalVisitor = null;   // 총방문자
        
        FileWriter fwCurrentVisitor = null;   // 현재접속자
        BufferedWriter bwCurrentVisitor = null;   // 현재접속자
        
        FileWriter fwTodayVisitor = null;   // 오늘 방문자
        
        FileWriter fwTotalCount = null; // 총 카운트
        
        // 현재 접속자 아이피 입력
        FileWriter fwCurrentIp = null;
        BufferedWriter bwCurrentIp = null;
        
        FileWriter fw3 = null;
        //++++++++++++++++++++++++++++++++++++++++++++++++
        
        try {
            String dir = MoumiConfig.getTotRoot().getPath() + System.getProperty("file.separator") + "monitor"
                            + System.getProperty("file.separator") + "user" + System.getProperty("file.separator");// 카운트 파일들을
                                                                                                                                                                                                            // 저장 하는 경로
                                                                                                                                                                                                            // 설정(절대경로)
            String filename = dir + "count.txt";
            String filename2 = dir + "ip_count.txt";
            String filename3 = dir + "today_count.txt";


            //3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Add by KWON,HAN
            LOG.debug("filename: {}", filename); 
            if(filename.contains("..") || filename. contains("/")) { // 특수문자열 검증
                LOG.debug("CustomBindingListener valueBound ===");
                LOG.debug("3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Not Test filename:{}", filename);
                LOG.debug("====================================");
                return;
            }
            LOG.debug("filename2: {}", filename2); 
            if(filename2.contains("..") || filename2. contains("/")) { // 특수문자열 검증
                LOG.debug("CustomBindingListener valueBound ===");
                LOG.debug("3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Not Test filename2:{}", filename2);
                LOG.debug("====================================");
                return;
            }   
            LOG.debug("filename3: {}", filename3); 
            if(filename3.contains("..") || filename3. contains("/")) { // 특수문자열 검증
                LOG.debug("CustomBindingListener valueBound ===");
                LOG.debug("3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Not Test filename3:{}", filename3);
                LOG.debug("====================================");
                return;
            }                         
            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


            File file = new File(filename);
            File file2 = new File(filename2);
            File file3 = new File(filename3);

            if (!file.exists())
                    file.createNewFile();
            if (!file2.exists())
                    file2.createNewFile();
            if (!file3.exists())
                    file3.createNewFile();

            //FileReader fr = new FileReader(filename);
            //BufferedReader br = new BufferedReader(fr);
            //FileReader fr2 = new FileReader(filename2);
            //BufferedReader br2 = new BufferedReader(fr2);
            //FileReader fr3 = new FileReader(filename3);
            //BufferedReader br3 = new BufferedReader(fr3);

            fr = new FileReader(filename);
            br = new BufferedReader(fr);
            
            fr2 = new FileReader(filename2);
            br2 = new BufferedReader(fr2);
            
            fr3 = new FileReader(filename3);
            br3 = new BufferedReader(fr3);
            
            //v2 36.경쟁조건 : 검사시점과 사용시점 (File)_CWE-367 : Update by YOUNGJUN,CHO
            //num = br.readLine();// 총 카운트 값 읽어오기
            while ((num = br.readLine()) != null) {
                num = num.trim();
            }
            //================================================

            while ((read_ip = br2.readLine()) != null) {
                    read_ip = read_ip.trim();
                    v.add(read_ip);
            }// 현재 접속자 아이피 가져오기

            //v2 36.경쟁조건 : 검사시점과 사용시점 (File)_CWE-367 : Update by YOUNGJUN,CHO
            //today_count = br3.readLine();// 오늘 방문자 카운트 가져오기
            while ((today_count = br3.readLine()) != null) {
                today_count = today_count.trim();
            }
            //================================================

            //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Delete by YOUNGJUN,CHO
            // finally 로 이동.
            //br.close();
            //br2.close();
            //br3.close();
            //------------------------------------------------
            
            // 총방문자 초기화
            if (num == null) {
                //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Update by YOUNGJUN,CHO
                fwTotalVisitor = new FileWriter(filename);
                fwTotalVisitor.write("0");
                num = "0";
                //fw.close();
                //================================================
            }

            // 현재접속자 초기화
            if (read_ip == null) {
                String start = "127.0.0.1";
                //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Update by YOUNGJUN,CHO
                fwCurrentVisitor = new FileWriter(filename2);
                bwCurrentVisitor = new BufferedWriter(fwCurrentVisitor);
                bwCurrentVisitor.write(start, 0, start.length());
                //bw.close();
                //fw.close();
                //================================================
            }

            // 오늘 방문자 초기화
            if (today_count == null) {
                //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Update by YOUNGJUN,CHO
                fwTodayVisitor = new FileWriter(filename3);
                fwTodayVisitor.write(chdate + ",1");
                today_num = "0";
                //fw3.close();
                //================================================
            }

            // 총 카운트 입력
            int now = (Integer.parseInt(num)) + 1;
            Integer new_num = new Integer(now);
            num = new_num.toString();
            
            //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Update by YOUNGJUN,CHO
            fwTotalCount = new FileWriter(filename);
            fwTotalCount.write(num);
            //fw.close();
            //================================================
            
            // 현재 접속자 아이피 입력
            //FileWriter fw2 = new FileWriter(filename2);
            //BufferedWriter bw2 = new BufferedWriter(fw2);
            fwCurrentIp = new FileWriter(filename2);
            bwCurrentIp = new BufferedWriter(fwCurrentIp);
            
            boolean match = false;
            for (int i = 0; i < v.size(); i++) {
                    String read = v.get(i);
                    if (read.equals(ip)) {
                            v.set(i, ip);// 아이피 같은지 비교 후 업데이트
                            match = true;
                    }

            }
            if (!match) {
                    v.add(ip);
            }
            for (int j = 0; j < v.size(); j++) {
                    String wr = v.get(j);
                    if (j != 0)
                            bwCurrentIp.newLine();
                    bwCurrentIp.write(wr, 0, wr.length());
            }
            //bw2.close();
            //fw2.close();

            // 오늘 방문자 입력
            if (today_count != null) {
                    String[] today_Cnvt = new String[3];
                    int idx = 0;
                    StringTokenizer strToken = new StringTokenizer(today_count, ",", true);
                    while (strToken.hasMoreTokens()) {
                            today = strToken.nextToken();
                            today_Cnvt[idx] = today;
                            idx++;
                    }

                    if (today_Cnvt[0].equals(chdate)) {
                            int today_num2 = (Integer.parseInt(today_Cnvt[2])) + 1;

                            Integer new_today = new Integer(today_num2);
                            today_num = new_today.toString();

                            //FileWriter fw3 = new FileWriter(filename3);
                            fw3 = new FileWriter(filename3);
                            fw3.write(chdate + "," + today_num);
                            //fw3.close();
                    } else {
                            today_num = "1";
                            //FileWriter fw3 = new FileWriter(filename3);
                            fw3 = new FileWriter(filename3);
                            fw3.write(chdate + "," + today_num);
                            //fw3.close();
                    }
            }
        //44.적절하지 않은 예외처리(광범위예외클래스)_CWE-754 Add by YOUNGJUN,CHO
        } catch (IOException ioex) {
            ioex.printStackTrace();
        } catch (NumberFormatException nfex) {
            nfex.printStackTrace();
        //++++++++++++++++++++++++++++++++++++++++++++++++
        } catch (Exception e) {
                throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (br2 != null) {
                try {
                    br2.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fr2 != null) {
                try {
                    fr2.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (br3 != null) {
                try {
                    br3.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fr3 != null) {
                try {
                    fr3.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fwTotalVisitor != null) {
                try {
                    fwTotalVisitor.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (bwCurrentVisitor != null) {
                try {
                    bwCurrentVisitor.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fwCurrentVisitor != null) {
                try {
                    fwCurrentVisitor.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fwTodayVisitor != null) {
                try {
                    fwTodayVisitor.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (bwCurrentIp != null) {
                try {
                    bwCurrentIp.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fwCurrentIp != null) {
                try {
                    fwCurrentIp.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            
            if (fw3 != null) {
                try {
                    fw3.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
        }
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        // 세션이 종료되었을 때
        List<String> v = new ArrayList<String>();
        
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        
        try {
            // String dir = Moumi.getTotRoot()+"/monitor/user/";
            String dir = MoumiConfig.getTotRoot().getPath() + System.getProperty("file.separator") + "monitor"
                            + System.getProperty("file.separator") + "user" + System.getProperty("file.separator");// 카운트 파일들을
                                                                                                                                                                                                                    // 설정(절대경로)
            String filename = dir + "ip_count.txt";

            //3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Add by KWON,HAN
            LOG.debug("filename: {}", filename); 
            if(filename.contains("..") || filename. contains("/")) { // 특수문자열 검증
                LOG.debug("CustomBindingListener valueUnbound ===");
                LOG.debug("4.디렉토리 경로 조작(getProperty)_CWE-22/23/36 : Not Test {}", filename);
                LOG.debug("======================================");
                return;
            }
            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            //FileReader fr = new FileReader(filename);
            //BufferedReader br = new BufferedReader(fr);
            fr = new FileReader(filename);
            br = new BufferedReader(fr);
            
            while ((read_ip = br.readLine()) != null) {
                read_ip = read_ip.trim();
                v.add(read_ip);
            }
            //br.close();

            //FileWriter fw = new FileWriter(filename);
            //BufferedWriter bw = new BufferedWriter(fw);
            fw = new FileWriter(filename);
            bw = new BufferedWriter(fw);
            
            for (int i = 0; i < v.size(); i++) {
                String read = v.get(i);
                if (read.equals(ip)) {
                    v.remove(i);
                }
            }

            for (int j = 0; j < v.size(); j++) {
                String wr = v.get(j);
                if (j != 0)
                    bw.newLine();
                bw.write(wr, 0, wr.length());
            }
            //bw.close();
            //fw.close();
        //44.적절하지 않은 예외처리(광범위예외클래스)_CWE-754 Add by YOUNGJUN,CHO
        } catch (IOException ioex) {
            ioex.printStackTrace();
        //++++++++++++++++++++++++++++++++++++++++++++++++    
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //v2 21.부적절한 자원 해제 (IO)_CWE-404 : Add by YOUNGJUN,CHO
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
            //++++++++++++++++++++++++++++++++++++++++++++++++
        }
    }
}
