package com.eactive.eai.custom.transformer.message;

import java.util.HashMap;

import com.eactive.eai.transformer.message.ISO8583Message;
import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.IsoType;
import com.solab.iso8583.MessageFactory;
import com.solab.iso8583.parse.FieldParseInfo;

/**
 * @formatter:off
 * ISO 8583 Silverlake(전문) 형식의 데이터를 변환하기 위한 메시지.(For KB Bukopin)
 * - Binary, EBCDIC
 *
 * [참조] https://en.wikipedia.org/wiki/ISO_8583
 * @formatter:on
 */
@SuppressWarnings("serial")
public class ISO8583SilverlakeMessage extends ISO8583Message {
	private static HashMap<Integer, FieldParseInfo> fullSpecMap = null;
	private static HashMap<Integer, String> fullFieldNameMap = null;
	private static String encode = "Cp1047"; // EBCDIC(1047)

	public MessageFactory<IsoMessage> createMessageFactory() {
		MessageFactory<IsoMessage> mf = new MessageFactory<>();
		mf.setUseBinaryMessages(true);
		mf.setUseBinaryBitmap(true);
		mf.setVariableLengthFieldsInHex(false);
		mf.setCharacterEncoding(encode);
		mf.setForceStringEncoding(true);
		return mf;
	}

	public HashMap<Integer, FieldParseInfo> getFullSpecMap(String enc) {
		if (fullSpecMap != null) {
			return fullSpecMap;
		}

		fullSpecMap = new HashMap<>();

		fullSpecMap.put(2, FieldParseInfo.getInstance(IsoType.LLBCDBIN, 10, encode));
		fullSpecMap.put(3, FieldParseInfo.getInstance(IsoType.BINARY, 3, encode));
		fullSpecMap.put(4, FieldParseInfo.getInstance(IsoType.BINARY, 6, encode));
		fullSpecMap.put(7, FieldParseInfo.getInstance(IsoType.BINARY, 5, encode));
		fullSpecMap.put(11, FieldParseInfo.getInstance(IsoType.BINARY, 3, encode));
		fullSpecMap.put(12, FieldParseInfo.getInstance(IsoType.BINARY, 3, encode));
		fullSpecMap.put(13, FieldParseInfo.getInstance(IsoType.BINARY, 2, encode));
		fullSpecMap.put(14, FieldParseInfo.getInstance(IsoType.BINARY, 2, encode));
		fullSpecMap.put(18, FieldParseInfo.getInstance(IsoType.BINARY, 2, encode));
		fullSpecMap.put(22, FieldParseInfo.getInstance(IsoType.BINARY, 2, encode));
		fullSpecMap.put(23, FieldParseInfo.getInstance(IsoType.BINARY, 2, encode));
		fullSpecMap.put(25, FieldParseInfo.getInstance(IsoType.BINARY, 1, encode));
		fullSpecMap.put(35, FieldParseInfo.getInstance(IsoType.LLBCDBIN, 19, encode));
		fullSpecMap.put(37, FieldParseInfo.getInstance(IsoType.ALPHA, 12, encode));
		fullSpecMap.put(38, FieldParseInfo.getInstance(IsoType.ALPHA, 6, encode));
		fullSpecMap.put(39, FieldParseInfo.getInstance(IsoType.ALPHA, 2, encode));
		fullSpecMap.put(41, FieldParseInfo.getInstance(IsoType.ALPHA, 8, encode));
		fullSpecMap.put(42, FieldParseInfo.getInstance(IsoType.ALPHA, 15, encode));
		fullSpecMap.put(43, FieldParseInfo.getInstance(IsoType.ALPHA, 40, encode));
		fullSpecMap.put(47, FieldParseInfo.getInstance(IsoType.LLLVAR, 256, encode));
		fullSpecMap.put(48, FieldParseInfo.getInstance(IsoType.LLLVAR, 256, encode));
		fullSpecMap.put(52, FieldParseInfo.getInstance(IsoType.BINARY, 8, encode));
		fullSpecMap.put(54, FieldParseInfo.getInstance(IsoType.LLLVAR, 120, encode));
		fullSpecMap.put(55, FieldParseInfo.getInstance(IsoType.LLLVAR, 255, encode));
		fullSpecMap.put(57, FieldParseInfo.getInstance(IsoType.LLLVAR, 255, encode));
		fullSpecMap.put(58, FieldParseInfo.getInstance(IsoType.LLLVAR, 255, encode));
		fullSpecMap.put(60, FieldParseInfo.getInstance(IsoType.LLLVAR, 120, encode));
		fullSpecMap.put(61, FieldParseInfo.getInstance(IsoType.LLLVAR, 120, encode));
		fullSpecMap.put(62, FieldParseInfo.getInstance(IsoType.LLLVAR, 512, encode));
		fullSpecMap.put(63, FieldParseInfo.getInstance(IsoType.LLLVAR, 512, encode));
		fullSpecMap.put(120, FieldParseInfo.getInstance(IsoType.LLLVAR, 700, encode));
		fullSpecMap.put(121, FieldParseInfo.getInstance(IsoType.LLLVAR, 500, encode));
		fullSpecMap.put(122, FieldParseInfo.getInstance(IsoType.LLLVAR, 350, encode));
		fullSpecMap.put(123, FieldParseInfo.getInstance(IsoType.LLLVAR, 999, encode));
		fullSpecMap.put(124, FieldParseInfo.getInstance(IsoType.LLLVAR, 450, encode));
		fullSpecMap.put(125, FieldParseInfo.getInstance(IsoType.LLLVAR, 255, encode));

		return fullSpecMap;
	}

	public String getFieldName(int key) {
		if (fullFieldNameMap == null) {
			fullFieldNameMap = new HashMap<>();
			fullFieldNameMap.put(1, "Secondary Bit Map");
			fullFieldNameMap.put(2, "Primary Account Number");
			fullFieldNameMap.put(3, "Processing code");
			fullFieldNameMap.put(4, "Amount,transaction");
			fullFieldNameMap.put(7, "Transmission date & time");
			fullFieldNameMap.put(11, "System audit trace number");
			fullFieldNameMap.put(12, "Time, local transaction");
			fullFieldNameMap.put(13, "Date, local transaction");
			fullFieldNameMap.put(14, "Date, expiration");
			fullFieldNameMap.put(18, "Merchant type");
			fullFieldNameMap.put(22, "POS entry mode");
			fullFieldNameMap.put(23, "Card sequence number");
			fullFieldNameMap.put(25, "POS condition code");
			fullFieldNameMap.put(35, "Track 2 data");
			fullFieldNameMap.put(37, "Retrieval reference number");
			fullFieldNameMap.put(38, "Authorisation ID response");
			fullFieldNameMap.put(39, "Response code");
			fullFieldNameMap.put(41, "Terminal ID");
			fullFieldNameMap.put(42, "Card acceptor ID");
			fullFieldNameMap.put(43, "Card acceptor name/location");
			fullFieldNameMap.put(47, "Private Use");
			fullFieldNameMap.put(48, "Request header");
			fullFieldNameMap.put(52, "PIN data");
			fullFieldNameMap.put(54, "Private Use");
			fullFieldNameMap.put(55, "ICC system related data");
			fullFieldNameMap.put(57, "Private Use");
			fullFieldNameMap.put(58, "Private Use");
			fullFieldNameMap.put(60, "Private Use");
			fullFieldNameMap.put(61, "Private Use");
			fullFieldNameMap.put(62, "Private Use");
			fullFieldNameMap.put(63, "Private Use");
			fullFieldNameMap.put(120, "Private Use");
			fullFieldNameMap.put(121, "Private Use");
			fullFieldNameMap.put(122, "Response detail");
			fullFieldNameMap.put(123, "Response detail");
			fullFieldNameMap.put(124, "Private Use");
			fullFieldNameMap.put(125, "Private Use");
		}

		return fullFieldNameMap.get(new Integer(key));
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("[ISO8583 Silverlake message]");
		sb.append("\n" + super.toString());
		sb.append("\n");
		return sb.toString();
	}
}