package nlib.util;

import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <pre>
 * @Class Name : StringUtil.java
 * 
 * @Description : 문자열 관련 공통 함수 모음 
 * 
 * 
 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
 *
 * </pre>
 *
 * @ ------------    --------    ---------------------------
 * @ 수정일                     수정자             수정내용
 * @ ------------    --------    ---------------------------
 * @ 2021. 6. 22.    KNKIM       최초 생성
 *
 * 
 * @author 이씨플라자 * DIGITALSHIP KNKIM
 * @since 2021. 6. 22.
 * @version 1.0
 *
 */
/**
 * <pre>
 * @Class Name : StringUtil.java
 * 
 * @Description : 
 * 
 * 
 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
 *
 * </pre>
 *
 * @ ------------    --------    ---------------------------
 * @ 수정일                     수정자             수정내용
 * @ ------------    --------    ---------------------------
 * @ 2021. 10. 25.    KNKIM       최초 생성
 *
 * 
 * @author 이씨플라자 * DIGITALSHIP KNKIM
 * @since 2021. 10. 25.
 * @version 1.0
 *
 */
public class StringUtil extends StringUtils {
	
	private static final Logger log = LoggerFactory.getLogger(StringUtil.class);
	
	/**
	 * Null 이거나, 빈문자열(공백 포함)인 경우, true를 리턴한다.
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(final CharSequence cs) {
		return isBlank(cs);
	}
	
	/**
	 * Null 이거나, 빈문자열(공백 포함)인 경우, replaceStr를 리턴한다.
	 * 
	 * @param str
	 * @return
	 */
	public static String getString(String str, String replaceStr) {
		if(isEmpty(str)) return replaceStr;
		else return str;
	}
	
	/**
	 * 0 이거나, 음수인 경우, replaceInt를 리턴한다.
	 * 
	 * @param str
	 * @return
	 */
	public static int getInt(int val, int replaceInt) {
		if(val <= 0) return replaceInt;
		else return val;
	}
	
	/**
	 * Null이 아니고 빈문자열(공백 포함)이 아닌 일반 문자가 존재하는 , true를 리턴한다.
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(String str) {
		return !isBlank(str);
	}
	
	/**
	 * 문자열을 정수형으로 변환하여 리턴한다. 만일 문자열이 null 또는 빈 문자열인 경우, -1을 리턴한다. 
	 * 
	 * @param str
	 * @return
	 */
	public static int toNumber(String str) {
		return toNumber(str, -1);
	}
	
	/**
	 * 문자열을 정수형으로 변환하여 리턴한다. 만일 문자열이 null 또는 빈 문자열인 경우, 기본값 정보 defaultInt를 리턴한다. 
	 * 
	 * @param str
	 * @param defaultInt
	 * @return
	 */
	public static int toNumber(String str, int defaultInt) {
		if(isEmpty(str)) return defaultInt;
		
		try {
			return Integer.parseInt(str.trim());
		} catch(Exception e) {}
		
		return defaultInt;
	}
	
	/**
	 * 현재 시각을 yyyyMMddhhmmssSSS 형식으로 리턴한다. 
	 *  
	 * @return
	 */
	public static String getTimeStamp() {

		return getTimeStamp(null);
	}
	
	public static String getTimeStamp(String pattern) {

		String rtnStr = null;

		// 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
		if(isEmpty(pattern)) pattern = "yyyyMMddhhmmssSSS";

		SimpleDateFormat sdfCurrent = new SimpleDateFormat(pattern, Locale.KOREA);
		Timestamp ts = new Timestamp(System.currentTimeMillis());

		rtnStr = sdfCurrent.format(ts.getTime());

		return rtnStr;
	}

	/**
	 * URLEncoder로 인코딩한다.
	 *  
	 * @return
	 */
	public static String encodeUrl(String str) {

		if(isEmpty(str)) return "";
		
		String encodedStr = null;
		
		try {
			encodedStr = URLEncoder.encode(str, "UTF-8");
		} catch(Exception e) {
			log.error("encodeUrl > Error while encoding for [" + str + "] " + e.toString());
			encodedStr = str;
		}
		return encodedStr;
	}
	
	/**
	 * URLDecoder로 디코딩한다.
	 *  
	 * @return
	 */
	public static String decodeUrl(String str) {

		if(isEmpty(str)) return "";
		
		String decodedStr = null;
		
		try {
			decodedStr = URLDecoder.decode(str, "UTF-8");
		} catch(Exception e) {
			log.error("encodeUrl > Error while encoding for [" + str + "] " + e.toString());
			decodedStr = str;
		}
		return decodedStr;
	}
	
	/**
	 * Base64로 인코딩한다.
	 *  
	 * @return
	 */
	public static String encodeBase64(String str) {

		if(isEmpty(str)) return "";
		
		Encoder encoder = Base64.getEncoder();
		return new String(encoder.encode(str.getBytes()));
	}
	
	/**
	 * Base64로 디코딩한다.
	 *  
	 * @return
	 */
	public static String decodeBase64(String str) {

		if(isEmpty(str)) return "";
		
		Decoder decoder = Base64.getDecoder();
		return new String(decoder.decode(str.getBytes()));
	}
	
	/**
	 * URL 주소에서 호스트명을 리턴한다.
	 * 
	 * 프로토콜://호스트.도메인/URI 에서 호스트명 리턴 
	 * (ex) https://seoul.nculture.org/abc/def.do  -> seoul 을 리턴한다. 
	 * 
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static String getHostName(String url) {
		if(isEmpty(url)) return "";
		
		String hostName = "";
		
		try {
			final URL urlObj = new URL(url);
			hostName = urlObj.getHost();
			if(isEmpty(hostName)) return "";
		} catch(Exception e) {
			log.error("[ERROR] getHostName(..) : " + e.toString());
			return "";
		}
		if("|localhost|nlib.nculture.org|nlib-dev.nculture.org|".contains(hostName)) hostName = "nlib";
		return (hostName.split("\\."))[0];
	}
	
	public static String addWebParamOfUrl(String url, String name, String value) {
		if(isEmpty(url)) return url;
		if(isEmpty(name)) return url;
		
		String delim = "?"; 
		if(url.contains("?")) {
			delim = "&";
		}
		
		return url + delim + name + "=" + getString(value, "");
	}
	
	public static String getSqlSearchKeyword(String str) {

		if(isNotEmpty(str)) {
			String ret = str.replaceAll("\\%", "\\\\%");
			return ret.replaceAll("_", "\\\\_");
	    }
		
		return str;
	}
	

	/**
	 * 날짜 문자열(YYYYMMDD)을 받아서 화면 출력용 날짜 형식 문자열(YYYY-MM-DD)로 리턴한다. 
	 * 
	 * @param dateStr
	 * @param defaultStr
	 * @return
	 */
	public static String formatDateStr(String dateStr, String defaultStr) {
		
		if(isEmpty(dateStr)) return defaultStr;
		
		String tmpDateStr = dateStr.trim();
		if(4 <= tmpDateStr.length() && tmpDateStr.length() < 6) return tmpDateStr.substring(0, 4); // 연도만 있는 경우 
		else if(6 <= tmpDateStr.length() && tmpDateStr.length() < 8) return tmpDateStr.substring(0, 4) + "-" + tmpDateStr.substring(4, 6); // YYYY-MM
		else if(8 <= tmpDateStr.length()) return tmpDateStr.substring(0, 4) + "-" + tmpDateStr.substring(4, 6) + "-" + tmpDateStr.substring(6, 8); // YYYY-MM-DD
		
		return defaultStr;
	}
	
	/** * 이메일 masking 후 리턴<br> * 변환 실패시 입력값 그대로 리턴<br> * 이메일 아이디 앞 2자리 노출<br> */ 
	public static String maskEmail(String email){ 
		try{ 
			if(StringUtils.isEmpty(email) || !email.contains("@")){
				return email; 
			} 
			String[] emailSplited = email.split("@"); 
			if(emailSplited.length != 2){ 
				return email; 
			} 
			if(emailSplited[0].length() > 2){
				String str="";
				for(int i=2;emailSplited[0].length()>i;i++)
				{
					str+="*";
				}
				return email.substring(0, 2) + str+"@" + emailSplited[1]; 
			}
			else{
				return email;
			} 
		}
		catch (Exception e){
		} return email; 
	}
	
	/** * 이름 masking 후 리턴<br> * 변환 실패시 입력값 그대로 리턴<br>*/ 
	public static String maskName(String name){ 
		try{ 
			if(StringUtils.isEmpty(name)){
				return name; 
			} 
			if(name.length() == 2){
				
				return name.substring(0, 1)+"*"; 
			}
			else if(name.length() >2){
				String str="";
				for(int i = 2; name.length()>i;i++)
					str+="*";
				return name.substring(0, 1)+str+name.substring(name.length()-1,name.length());
			} 
		}
		catch (Exception e){
		} return name; 
	}
	
}
