/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKCrecaMeiginChk
*	ソースファイル名：JKKCrecaMeiginChk.java
*	作成者			：富士通
*	日付			：2022年12月12日
*＜機能概要＞
*	クレジットカード名義人チェックの結果を判定する。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v63.00.00	2022/12/12  FJ)渋谷		【ANK-4329-00-00】クレジットカード認証時の3Dセキュア対応
*
**********************************************************************/
package eo.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
 * クレジットカードの支払審査結果を判定する。
 * @author 富士通
 */

public class JKKCrecaMeiginChk 
{
	/** 半角スペース */
	private static final String HALF_SPACE = " ";
	
	/** 全角スペース */
	private static final String FULL_SPACE = "　";
	
	/** 空文字 */
	private static final String EMPTY_STRING = "";
	
	/** ローマ字表 */
	private static final HashMap<String, String[]> romaji_chg_map = new HashMap<String, String[]>();
	
	/**
	 * 引数文字列をStringBulderで連結する。
	 * (引数がnullの場合空文字に置き換えて連結する)
	 * @param strs
	 * @return
	 */
	public static String strBuilder(String ...strs){
		StringBuilder sb = new StringBuilder("");
		for(String str : strs){
			sb.append(str == null ? "" : str);
		}
		return sb.toString();
	}
	/**
	 * カナ氏名ローマ字変換正誤チェック
	 * 
	 * @param kana		カタカナ（カナ氏名）
	 * @param romaji	ローマ字
	 * @return	true（OK）/false（要確認）
	 */
	public static boolean checkKanaToRomaji(String kana, String romaji) {
		
		// 必須チェック
		if ( JKKStringUtil.isNullBlank(kana) || JKKStringUtil.isNullBlank(romaji)){
			return false;
		}
		
		// カタカナ（カナ氏名）からスペース（半角）を全角に変換
		kana = kana.replaceAll(HALF_SPACE, FULL_SPACE);
		// ローマ字からスペース（全角）を半角に変換
		romaji = romaji.replaceAll(FULL_SPACE, HALF_SPACE);
		
		int intCnt = 0;
	    int intS = 0;
	    
	    // カタカナ（カナ氏名）スペース数カウント
		while (intS < kana.length())
		{
			int index = kana.indexOf(FULL_SPACE, intS);
			if (index == -1)
			{
				break;
			}
			intS = index + FULL_SPACE.length();
			intCnt++;
		}

		// カタカナ（カナ氏名）分割（姓→名パターン）
		String strKana[] = separateByShiteKeta(kana.replaceAll(FULL_SPACE, EMPTY_STRING), 1);
		// ローマ字からスペース（半角）をブランクに変換
		String strRomaji = romaji.replaceAll(HALF_SPACE, EMPTY_STRING);
		
		if (intCnt == 1){
			// カタカナ（カナ氏名）分割（名→姓パターン）
			String strKanaRev[] = separateByShiteKeta(kana.substring(intS).concat(kana.substring(0, intS - 1)), 1);
			if (judgeKanaToRomaji(strKanaRev, strRomaji)){
				return true;
			}
		}
		
		return judgeKanaToRomaji(strKana, strRomaji);
		
	}

	/**
	 * カタカナ（カナ氏名）からローマ字に変換し、引数のローマ字が正しく設定されているかチェックする処理
	 * 
	 * @param kana[]	カタカナ（カナ氏名）配列
	 * @param romaji	ローマ字
	 * @return	true/false
	 */
	private static boolean judgeKanaToRomaji (String kana[], String romaji){
		
		KanaToRomajiDTO();
		int intRomajiKeta = 0;
		boolean blnSokuonFlg = false;
		
		try{
			for (int i = 0; i < kana.length; i++) {
				String strTgtKana = kana[i];
				if (i != 0 && i != kana.length - 1 && "ッ".equals(strTgtKana)){
					blnSokuonFlg = true;
					continue;
				}
				if (i != kana.length - 1){
					if ("キ".equals(strTgtKana) || "シ".equals(strTgtKana) || "チ".equals(strTgtKana)
							|| "ニ".equals(strTgtKana) || "ヒ".equals(strTgtKana) || "ミ".equals(strTgtKana)
							|| "リ".equals(strTgtKana) || "ギ".equals(strTgtKana) || "ジ".equals(strTgtKana)
							|| "ビ".equals(strTgtKana) || "ピ".equals(strTgtKana)){
						if ("ャ".equals(kana[i + 1]) || "ュ".equals(kana[i + 1]) || "ョ".equals(kana[i + 1])){
							strTgtKana = strBuilder(strTgtKana, kana[i + 1]);
							i++;
						}
					}
				}
				//　チェックするカナ文字が変換表に存在しない場合
				if (romaji_chg_map.containsKey(strTgtKana)){
					boolean blnMatchFlg = false;
					for (int j = 0; j < romaji_chg_map.get(strTgtKana).length; j++) {
						
						String strGetRomaji = romaji_chg_map.get(strTgtKana)[j];
						if (blnSokuonFlg){
							if ("CH".equals(strGetRomaji.substring(0, 2))){
								strGetRomaji = strBuilder("T", strGetRomaji);
							} else {
								strGetRomaji = strBuilder(strGetRomaji.substring(0, 1), strGetRomaji);
							}
						}
						if (romaji.length() < intRomajiKeta + strGetRomaji.length()){
							continue;
						}
						String strTgtRomaji = romaji.substring(intRomajiKeta, intRomajiKeta + strGetRomaji.length());
						if (strGetRomaji.equals(strTgtRomaji)) {
							blnMatchFlg = true;
							intRomajiKeta = intRomajiKeta + strGetRomaji.length();
							
							if ("N".equals(strTgtRomaji) && romaji.length() > intRomajiKeta){
								if ("N".equals(romaji.substring(intRomajiKeta, intRomajiKeta + 1))) {
									if (i == kana.length - 1){
										intRomajiKeta = intRomajiKeta + 1;
									} else {
										if (("ナ".equals(kana[i + 1]) || "ニ".equals(kana[i + 1])
												|| "ヌ".equals(kana[i + 1]) || "ネ".equals(kana[i + 1]) || "ノ".equals(kana[i + 1]))){
											if ("N".equals(romaji.substring(intRomajiKeta + 1, intRomajiKeta + 2))){
												intRomajiKeta = intRomajiKeta + 1;
											}
										} else {
											intRomajiKeta = intRomajiKeta + 1;
										}
									}
								}
							}
							break;
						}
					}
					
					if (blnSokuonFlg){
						blnSokuonFlg = false;
					}
					
					if (!blnMatchFlg){
						return false;
					}
					
				} else {
					return false;
				}
			}
			if(romaji.length() > intRomajiKeta){
				return false;
			}
		} catch (Exception e) {
			// 例外エラーの場合はfalse
			return false;
		}
		return true;
	}
	/**
	 * 対象文字列を指定した桁で分割してString配列で返す。
	 * null または 空文字の場合は空配列
	 * 指定桁で分割して、あまり文字が出た場合も最後のインデックスに格納
	 * @param target
	 * @param keta
	 * @return
	 */
	public static String[] separateByShiteKeta(String target , int keta){
		if(target == null || target.length() == 0){
			return new String[0]; //空の配列を返す
		}
		List<String> list = new ArrayList<String>();
		String zanTarget = target;
		StringBuilder rtnSb = new StringBuilder();
		String addStr = EMPTY_STRING;
		while(zanTarget.length()>0){
			if(zanTarget.length() > keta){
				addStr = zanTarget.substring(0, keta);
				list.add(addStr);
				zanTarget = zanTarget.substring(addStr.length());
			}else{
				list.add(zanTarget);
				zanTarget = zanTarget.replaceFirst(zanTarget, EMPTY_STRING);
				break;				
			}
		}
		return (String[])list.toArray(new String[0]);
	}
	/**
	 *ローマ字変換用ハッシュマップを作成する。
	 * @throws Exception
	 */
	public static void KanaToRomajiDTO() {
		
		romaji_chg_map.put("ア", new String[]{"A"});
		romaji_chg_map.put("イ", new String[]{"I"});
		romaji_chg_map.put("ウ", new String[]{"U"});
		romaji_chg_map.put("エ", new String[]{"E"});
		romaji_chg_map.put("オ", new String[]{"O"});
		romaji_chg_map.put("カ", new String[]{"KA","CA"});
		romaji_chg_map.put("キ", new String[]{"KI"});
		romaji_chg_map.put("ク", new String[]{"KU"});
		romaji_chg_map.put("ケ", new String[]{"KE"});
		romaji_chg_map.put("コ", new String[]{"KO"});
		romaji_chg_map.put("サ", new String[]{"SA"});
		romaji_chg_map.put("シ", new String[]{"SHI","SI"});
		romaji_chg_map.put("ス", new String[]{"SU"});
		romaji_chg_map.put("セ", new String[]{"SE"});
		romaji_chg_map.put("ソ", new String[]{"SO"});
		romaji_chg_map.put("タ", new String[]{"TA"});
		romaji_chg_map.put("チ", new String[]{"CHI","TI"});
		romaji_chg_map.put("ツ", new String[]{"TSU","TU","THU"});
		romaji_chg_map.put("テ", new String[]{"TE"});
		romaji_chg_map.put("ト", new String[]{"TO"});
		romaji_chg_map.put("ナ", new String[]{"NA"});
		romaji_chg_map.put("ニ", new String[]{"NI"});
		romaji_chg_map.put("ヌ", new String[]{"NU"});
		romaji_chg_map.put("ネ", new String[]{"NE"});
		romaji_chg_map.put("ノ", new String[]{"NO"});
		romaji_chg_map.put("ハ", new String[]{"HA"});
		romaji_chg_map.put("ヒ", new String[]{"HI"});
		romaji_chg_map.put("フ", new String[]{"FU","HU"});
		romaji_chg_map.put("ヘ", new String[]{"HE"});
		romaji_chg_map.put("ホ", new String[]{"HO"});
		romaji_chg_map.put("マ", new String[]{"MA"});
		romaji_chg_map.put("ミ", new String[]{"MI"});
		romaji_chg_map.put("ム", new String[]{"MU"});
		romaji_chg_map.put("メ", new String[]{"ME"});
		romaji_chg_map.put("モ", new String[]{"MO"});
		romaji_chg_map.put("ヤ", new String[]{"YA"});
		romaji_chg_map.put("ユ", new String[]{"YU"});
		romaji_chg_map.put("ヨ", new String[]{"YO"});
		romaji_chg_map.put("ラ", new String[]{"RA","LA"});
		romaji_chg_map.put("リ", new String[]{"RI","LI"});
		romaji_chg_map.put("ル", new String[]{"RU","LU"});
		romaji_chg_map.put("レ", new String[]{"RE","LE"});
		romaji_chg_map.put("ロ", new String[]{"RO","LO"});
		romaji_chg_map.put("ワ", new String[]{"WA"});
		romaji_chg_map.put("ヲ", new String[]{"O"});
		romaji_chg_map.put("ン", new String[]{"N","NN"});
		romaji_chg_map.put("ガ", new String[]{"GA"});
		romaji_chg_map.put("ギ", new String[]{"GI"});
		romaji_chg_map.put("グ", new String[]{"GU"});
		romaji_chg_map.put("ゲ", new String[]{"GE"});
		romaji_chg_map.put("ゴ", new String[]{"GO"});
		romaji_chg_map.put("ザ", new String[]{"ZA"});
		romaji_chg_map.put("ジ", new String[]{"JI","ZI"});
		romaji_chg_map.put("ズ", new String[]{"ZU"});
		romaji_chg_map.put("ゼ", new String[]{"ZE"});
		romaji_chg_map.put("ゾ", new String[]{"ZO"});
		romaji_chg_map.put("ダ", new String[]{"DA"});
		romaji_chg_map.put("ヂ", new String[]{"JI","DI"});
		romaji_chg_map.put("ヅ", new String[]{"ZU","DU"});
		romaji_chg_map.put("デ", new String[]{"DE"});
		romaji_chg_map.put("ド", new String[]{"DO"});
		romaji_chg_map.put("バ", new String[]{"BA"});
		romaji_chg_map.put("ビ", new String[]{"BI"});
		romaji_chg_map.put("ブ", new String[]{"BU"});
		romaji_chg_map.put("ベ", new String[]{"BE"});
		romaji_chg_map.put("ボ", new String[]{"BO"});
		romaji_chg_map.put("パ", new String[]{"PA"});
		romaji_chg_map.put("ピ", new String[]{"PI"});
		romaji_chg_map.put("プ", new String[]{"PU"});
		romaji_chg_map.put("ペ", new String[]{"PE"});
		romaji_chg_map.put("ポ", new String[]{"PO"});
		romaji_chg_map.put("キャ", new String[]{"KYA"});
		romaji_chg_map.put("キュ", new String[]{"KYU"});
		romaji_chg_map.put("キョ", new String[]{"KYO"});
		romaji_chg_map.put("シャ", new String[]{"SHA","SYA"});
		romaji_chg_map.put("シュ", new String[]{"SHU","SYU"});
		romaji_chg_map.put("ショ", new String[]{"SHO","SYO"});
		romaji_chg_map.put("チャ", new String[]{"CHA","CYA","TYA"});
		romaji_chg_map.put("チュ", new String[]{"CHU","CYU","TYU"});
		romaji_chg_map.put("チョ", new String[]{"CHO","CYO","TYO"});
		romaji_chg_map.put("ニャ", new String[]{"NYA"});
		romaji_chg_map.put("ニュ", new String[]{"NYU"});
		romaji_chg_map.put("ニョ", new String[]{"NYO"});
		romaji_chg_map.put("ヒャ", new String[]{"HYA"});
		romaji_chg_map.put("ヒュ", new String[]{"HYU"});
		romaji_chg_map.put("ヒョ", new String[]{"HYO"});
		romaji_chg_map.put("ミャ", new String[]{"MYA"});
		romaji_chg_map.put("ミュ", new String[]{"MYU"});
		romaji_chg_map.put("ミョ", new String[]{"MYO"});
		romaji_chg_map.put("リャ", new String[]{"RYA"});
		romaji_chg_map.put("リュ", new String[]{"RYU"});
		romaji_chg_map.put("リョ", new String[]{"RYO"});
		romaji_chg_map.put("ギャ", new String[]{"GYA"});
		romaji_chg_map.put("ギュ", new String[]{"GYU"});
		romaji_chg_map.put("ギョ", new String[]{"GYO"});
		romaji_chg_map.put("ジャ", new String[]{"JA","ZYA"});
		romaji_chg_map.put("ジュ", new String[]{"JU","JYU"});
		romaji_chg_map.put("ジョ", new String[]{"JO","JYO"});
		romaji_chg_map.put("ビャ", new String[]{"BYA"});
		romaji_chg_map.put("ビュ", new String[]{"BYU"});
		romaji_chg_map.put("ビョ", new String[]{"BYO"});
		romaji_chg_map.put("ピャ", new String[]{"PYA"});
		romaji_chg_map.put("ピュ", new String[]{"PYU"});
		romaji_chg_map.put("ピョ", new String[]{"PYO"});
		romaji_chg_map.put("ー", new String[]{"-"});
	}
}
