package egovframework.util;

import javax.servlet.http.HttpServletRequest;

/**
 * packageName    : egovframework.util
 * fileName       : ClientInfoUtil
 * author         : 시스템 관리자
 * date           : 2025-05-22
 * description    : 클라이언트 정보(디바이스, OS, 브라우저 등) 추출 유틸리티 클래스
 * ===========================================================
 * DATE              AUTHOR             NOTE
 * -----------------------------------------------------------
 * 2025-05-22        시스템 관리자       최초 생성
 */
public class ClientInfoUtil {

    /**
     * User-Agent 문자열에서 디바이스 정보를 추출합니다.
     * 
     * @param userAgent 사용자 에이전트 문자열
     * @return 디바이스 정보
     */
    public static String extractDeviceInfo(String userAgent) {
        if (userAgent == null || userAgent.isEmpty()) {
            return "Unknown";
        }

        userAgent = userAgent.toLowerCase();
        StringBuilder deviceInfo = new StringBuilder();

        // OS 정보 추출
        String osInfo = extractOsInfo(userAgent);

        // 디바이스 유형 및 제조사 정보 추출
        String deviceType = extractDeviceType(userAgent);

        // 브라우저 정보 추출
        String browserInfo = extractBrowserInfo(userAgent);

        // 정보 조합
        if (!deviceType.isEmpty()) {
            deviceInfo.append(deviceType);
        }

        if (!osInfo.isEmpty()) {
            if (deviceInfo.length() > 0) {
                deviceInfo.append(" - ");
            }
            deviceInfo.append(osInfo);
        }

        // 모바일/태블릿이 아닌 경우에만 브라우저 정보 추가
        if (!deviceType.contains("Mobile") && !deviceType.contains("Tablet") && !browserInfo.isEmpty()) {
            if (deviceInfo.length() > 0) {
                deviceInfo.append(" - ");
            }
            deviceInfo.append(browserInfo);
        }

        return deviceInfo.length() > 0 ? deviceInfo.toString() : "Unknown Device";
    }

    /**
     * User-Agent 문자열에서 OS 정보를 추출합니다.
     * 
     * @param userAgent 사용자 에이전트 문자열
     * @return OS 정보
     */
    public static String extractOsInfo(String userAgent) {
        // Windows 버전 확인
        if (userAgent.contains("windows")) {
            if (userAgent.contains("windows nt 10")) {
                return "Windows 10";
            } else if (userAgent.contains("windows nt 6.3")) {
                return "Windows 8.1";
            } else if (userAgent.contains("windows nt 6.2")) {
                return "Windows 8";
            } else if (userAgent.contains("windows nt 6.1")) {
                return "Windows 7";
            } else if (userAgent.contains("windows nt 6.0")) {
                return "Windows Vista";
            } else if (userAgent.contains("windows nt 5.1") || userAgent.contains("windows xp")) {
                return "Windows XP";
            } else {
                return "Windows";
            }
        }

        // Mac OS 버전 확인
        if (userAgent.contains("macintosh") || userAgent.contains("mac os x")) {
            if (userAgent.contains("mac os x 10_15")) {
                return "macOS Catalina";
            } else if (userAgent.contains("mac os x 10_14")) {
                return "macOS Mojave";
            } else if (userAgent.contains("mac os x 10_13")) {
                return "macOS High Sierra";
            } else if (userAgent.contains("mac os x 10_12")) {
                return "macOS Sierra";
            } else {
                return "Mac OS";
            }
        }

        // 기타 OS 확인
        if (userAgent.contains("android")) {
            // Android 버전 추출
            int startIndex = userAgent.indexOf("android ");
            if (startIndex != -1) {
                int endIndex = userAgent.indexOf(";", startIndex);
                if (endIndex != -1) {
                    return "Android " + userAgent.substring(startIndex + 8, endIndex).trim();
                }
            }
            return "Android";
        } else if (userAgent.contains("ios")) {
            return "iOS";
        } else if (userAgent.contains("iphone os") || userAgent.contains("cpu os")) {
            // iOS 버전 추출
            int startIndex = userAgent.contains("iphone os ") ? userAgent.indexOf("iphone os ") + 10 : userAgent.indexOf("cpu os ") + 7;
            if (startIndex != -1) {
                int endIndex = userAgent.indexOf(" ", startIndex);
                if (endIndex != -1) {
                    String version = userAgent.substring(startIndex, endIndex).trim().replace("_", ".");
                    return "iOS " + version;
                }
            }
            return "iOS";
        } else if (userAgent.contains("linux")) {
            return "Linux";
        } else if (userAgent.contains("unix")) {
            return "Unix";
        }

        return "";
    }

    /**
     * User-Agent 문자열에서 디바이스 유형 및 제조사 정보를 추출합니다.
     * 
     * @param userAgent 사용자 에이전트 문자열
     * @return 디바이스 유형 및 제조사 정보
     */
    public static String extractDeviceType(String userAgent) {
        // 모바일 디바이스 확인
        if (userAgent.contains("mobile")) {
            if (userAgent.contains("iphone")) {
                return "iPhone";
            } else if (userAgent.contains("android")) {
                // 안드로이드 제조사 확인
                if (userAgent.contains("samsung")) {
                    return "Samsung Mobile";
                } else if (userAgent.contains("lg")) {
                    return "LG Mobile";
                } else if (userAgent.contains("huawei")) {
                    return "Huawei Mobile";
                } else if (userAgent.contains("xiaomi")) {
                    return "Xiaomi Mobile";
                } else if (userAgent.contains("oppo")) {
                    return "OPPO Mobile";
                } else if (userAgent.contains("vivo")) {
                    return "Vivo Mobile";
                } else if (userAgent.contains("oneplus")) {
                    return "OnePlus Mobile";
                } else if (userAgent.contains("motorola")) {
                    return "Motorola Mobile";
                } else if (userAgent.contains("nokia")) {
                    return "Nokia Mobile";
                } else {
                    return "Android Mobile";
                }
            } else if (userAgent.contains("windows phone")) {
                return "Windows Phone";
            } else {
                return "Mobile Device";
            }
        }

        // 태블릿 확인
        if (userAgent.contains("ipad")) {
            return "iPad";
        } else if (userAgent.contains("android") && !userAgent.contains("mobile")) {
            // 안드로이드 태블릿 제조사 확인
            if (userAgent.contains("samsung")) {
                return "Samsung Tablet";
            } else if (userAgent.contains("huawei")) {
                return "Huawei Tablet";
            } else if (userAgent.contains("lenovo")) {
                return "Lenovo Tablet";
            } else if (userAgent.contains("asus")) {
                return "Asus Tablet";
            } else if (userAgent.contains("amazon") || userAgent.contains("kindle")) {
                return "Amazon Tablet";
            } else {
                return "Android Tablet";
            }
        } else if (userAgent.contains("tablet")) {
            return "Tablet";
        }

        return "";
    }

    /**
     * User-Agent 문자열에서 브라우저 정보를 추출합니다.
     * 
     * @param userAgent 사용자 에이전트 문자열
     * @return 브라우저 정보
     */
    public static String extractBrowserInfo(String userAgent) {
        if (userAgent.contains("edge/") || userAgent.contains("edg/")) {
            return "Edge Browser";
        } else if (userAgent.contains("chrome/")) {
            return "Chrome Browser";
        } else if (userAgent.contains("safari/") && !userAgent.contains("chrome/")) {
            return "Safari Browser";
        } else if (userAgent.contains("firefox/")) {
            return "Firefox Browser";
        } else if (userAgent.contains("opera/") || userAgent.contains("opr/")) {
            return "Opera Browser";
        } else if (userAgent.contains("msie") || userAgent.contains("trident/")) {
            return "Internet Explorer";
        }

        return "";
    }

    /**
     * 클라이언트 IP 주소를 가져옵니다.
     * 
     * @param request HTTP 요청 객체
     * @return 클라이언트 IP 주소
     */
    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }
}