package com.rttsweb.querysurge;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.ibm.as400.access.AS400Text;

/*
 * Copyright (c) 2018 Real-Time Technology Solutions, Inc. All Rights Reserved.
 */

public class EbcdicToAsciiConv {
	
	/*
	 * http://jt400.sourceforge.net/
	 * https://sourceforge.net/projects/jt400/
	 * JTOpen is the open source version of the IBM Toolbox for Java licensed program product, and contains the identical code.
	 */
	
	public static void ebcdicToAsciiConvert(String inputFilePath, String outputAsciiFilePath, int recLenInBytes, String inCharsetName, String convCharsetName, String writeCharsetName, boolean addLinebreaks) throws IOException {
		// READ EBCDIC FROM FILE
		Charset inCharset = charsetResolver(inCharsetName);
		String ebcdicFromFile = new String(Files.readAllBytes(Paths.get(inputFilePath)), inCharset);
		
		// CONVERT EBCDIC TO ASCII
		Charset convCharset = charsetResolver(convCharsetName);
		String ebcdicDataFromFileToAscii = ebcdicToAscii(ebcdicFromFile, convCharset);
		
		// WRITE ASCII FILE
		Charset writeCharset = charsetResolver(writeCharsetName);
		writeAsciiBufferToFile(ebcdicDataFromFileToAscii, outputAsciiFilePath, recLenInBytes, writeCharset, addLinebreaks);		
	}
	
	private static Charset charsetResolver(String charsetName) {
		Charset charset = null;
		switch (charsetName) {
		case "UTF-8":
			charset = StandardCharsets.UTF_8;
			break;
		case "UTF-16":
			charset = StandardCharsets.UTF_16;
			break;
		case "UTF-16BE":
			charset = StandardCharsets.UTF_16BE;
			break;
		case "UTF-16LE":
			charset = StandardCharsets.UTF_16LE;
			break;
		case "US-ASCII": case "USASCII":
			charset = StandardCharsets.US_ASCII;
			break;
		case "ISO-8859-1": case "ISO_8859_1":
			charset = StandardCharsets.ISO_8859_1;
			break;
		}
		return charset;
	}
	
	private static String ebcdicToAscii(String ebcidicFromFile, Charset charSet) {
		byte [] ebcdicByteArr = ebcidicFromFile.toString().getBytes(charSet);
        int textLen = ebcdicByteArr.length;
        AS400Text textConverter = new AS400Text(textLen);
        String asciiBuffer = ((String) textConverter.toObject(ebcdicByteArr)).substring(0, textLen);
        return asciiBuffer;
    }
    
	private static void writeAsciiBufferToFile(String asciiData, String asciiFilePath, int recLenInBytes, Charset charSet, boolean addLinebreaks) throws IOException {
    	StringBuilder asciiBuffer = new StringBuilder(asciiData);
				
		if (addLinebreaks) {
			int pos = 0;
			while (true) {
				pos += recLenInBytes;
				asciiBuffer.insert(pos, '\n');
				pos++;
				if (pos >= (asciiBuffer.length() - recLenInBytes)) {
					break;
				}
			}
			
			List<String> asciiDataAsList = new ArrayList<String>(Arrays.asList(asciiBuffer.toString().split("\n")));
			Files.write(Paths.get(asciiFilePath), asciiDataAsList, charSet);
		} else {
			Files.write(Paths.get(asciiFilePath), asciiData.getBytes(charSet));
		}
    }
}
