// Path: copybook4java/src/main/java/com/nordea/oss/ByteUtils.java
// public class ByteUtils {
// 
//     public static boolean allEquals(byte[] array, byte value, int offset, int maxLength) {
//         maxLength = Math.min(offset + maxLength, array.length);
//         for(int i = offset; i < maxLength; i++) {
//             if(array[i] != value) {
//                 return false;
//             }
//         }
//         return true;
//     }
// 
//     public static int indexOf(byte[] array, byte needle, int offset, int maxLength) {
//         int result = -1;
//         maxLength = Math.min(offset + maxLength, array.length);
//         for(int i = offset; i < maxLength; i++) {
//             if(array[i] == needle) {
//                 result = i;
//                 break;
//             }
//         }
//         return result;
//     }
// 
//     public static byte[] trim(byte[] src, byte padding, boolean right, int minLength) {
//         if(src.length < minLength) {
//             throw new RuntimeException("src array is smaller than minLength: " + src.length + " < " + minLength);
//         }
//         if(right) {
//             int offset;
//             for (offset = src.length - 1; offset > minLength - 1; offset--) {  // [44, 32]
//                 if(padding != src[offset]) {
//                     break;
//                 }
//             }
//             if(offset < 0) {
//                 return new byte[0];
//             } else if (offset < src.length - 1){
//                 return Arrays.copyOfRange(src, 0, offset + 1);
//             }
// 
//         } else {
//             int offset;
//             for (offset = 0; offset < src.length - minLength; offset++) {
//                 if(padding != src[offset]) {
//                     break;
//                 }
//             }
//             if(offset == src.length) {
//                 return new byte[0];
//             } else if(offset > 0) {
//                 return Arrays.copyOfRange(src, offset, src.length);
//             }
//         }
// 
//         return src;
//     }
// 
//     public static byte[] toByteArray(InputStream inputStream) throws IOException {
//         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 
//         byte[] buf = new byte[8192];
//         while(true) {
//             int r = inputStream.read(buf);
//             if(r == -1) {
//                 break;
//             }
//             outputStream.write(buf, 0, r);
//         }
// 
//         return outputStream.toByteArray();
//     }
// }


import com.nordea.oss.ByteUtils;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import javax.script.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
                    .collect(Collectors.toList());

        } else if (inputFile.isFile()) {
            inputFiles.add(inputFile);
        }

        for(File inFile : inputFiles) {
            String packageName = inFile.getCanonicalFile().getParent().substring(inputPath.length()).replace('\\', '.').replace('/', '.').replace('_', '.');
            packageName = packageName.isEmpty() ? packageRootName : packageRootName + "." + packageName.substring(1);
            String rootClassName = getClassNameFromFile(inFile);
            List<String> outClasses = convert(new FileInputStream(inFile), packageName, rootClassName, accessor, charset, subClassHandling, rootClassName);
            for(String outClass : outClasses) {
                Matcher classNameMatcher = re_className.matcher(outClass);
                if (classNameMatcher.find()) {
                    String className = classNameMatcher.group(1);
                    Path outPath = Paths.get(outputPath, packageName.replace('.', '/'),className + ".java");
                    outPath.getParent().toFile().mkdirs();
                    System.out.println("  " + outPath);
                    Files.write(outPath, outClass.getBytes(StandardCharsets.UTF_8));
                }
            }
        }
    }

    public List<String> convert(String copybookString, String packageName, String rootClassName, String accessor, String charset, String subClassHandling, String wrapperClassName) throws Exception {
        ScriptObjectMirror results = (ScriptObjectMirror) invocable.invokeFunction("convertCopybook", packageName, rootClassName, copybookString, accessor, charset, subClassHandling, wrapperClassName);
        return Arrays.asList(results.values().toArray(new String[results.size()]));
    }

    public List<String> convert(InputStream copybookStream, String packageName, String rootClassName, String accessor, String charset, String subClassHandling, String wrapperClassName) throws Exception {
// Path: copybook4java/src/main/java/com/nordea/oss/ByteUtils.java
// public class ByteUtils {
// 
//     public static boolean allEquals(byte[] array, byte value, int offset, int maxLength) {
//         maxLength = Math.min(offset + maxLength, array.length);
//         for(int i = offset; i < maxLength; i++) {
//             if(array[i] != value) {
//                 return false;
//             }
//         }
//         return true;
//     }
// 
//     public static int indexOf(byte[] array, byte needle, int offset, int maxLength) {
//         int result = -1;
//         maxLength = Math.min(offset + maxLength, array.length);
//         for(int i = offset; i < maxLength; i++) {
//             if(array[i] == needle) {
//                 result = i;
//                 break;
//             }
//         }
//         return result;
//     }
// 
//     public static byte[] trim(byte[] src, byte padding, boolean right, int minLength) {
//         if(src.length < minLength) {
//             throw new RuntimeException("src array is smaller than minLength: " + src.length + " < " + minLength);
//         }
//         if(right) {
//             int offset;
//             for (offset = src.length - 1; offset > minLength - 1; offset--) {  // [44, 32]
//                 if(padding != src[offset]) {
//                     break;
//                 }
//             }
//             if(offset < 0) {
//                 return new byte[0];
//             } else if (offset < src.length - 1){
//                 return Arrays.copyOfRange(src, 0, offset + 1);
//             }
// 
//         } else {
//             int offset;
//             for (offset = 0; offset < src.length - minLength; offset++) {
//                 if(padding != src[offset]) {
//                     break;
//                 }
//             }
//             if(offset == src.length) {
//                 return new byte[0];
//             } else if(offset > 0) {
//                 return Arrays.copyOfRange(src, offset, src.length);
//             }
//         }
// 
//         return src;
//     }
// 
//     public static byte[] toByteArray(InputStream inputStream) throws IOException {
//         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 
//         byte[] buf = new byte[8192];
//         while(true) {
//             int r = inputStream.read(buf);
//             if(r == -1) {
//                 break;
//             }
//             outputStream.write(buf, 0, r);
//         }
// 
//         return outputStream.toByteArray();
//     }
// }


// Path: copybook4java-codegen-maven-plugin/src/main/java/com/nordea/oss/copybook/codegen/CopyBookConverter.java
import com.nordea.oss.ByteUtils;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import javax.script.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

                    .collect(Collectors.toList());

        } else if (inputFile.isFile()) {
            inputFiles.add(inputFile);
        }

        for(File inFile : inputFiles) {
            String packageName = inFile.getCanonicalFile().getParent().substring(inputPath.length()).replace('\\', '.').replace('/', '.').replace('_', '.');
            packageName = packageName.isEmpty() ? packageRootName : packageRootName + "." + packageName.substring(1);
            String rootClassName = getClassNameFromFile(inFile);
            List<String> outClasses = convert(new FileInputStream(inFile), packageName, rootClassName, accessor, charset, subClassHandling, rootClassName);
            for(String outClass : outClasses) {
                Matcher classNameMatcher = re_className.matcher(outClass);
                if (classNameMatcher.find()) {
                    String className = classNameMatcher.group(1);
                    Path outPath = Paths.get(outputPath, packageName.replace('.', '/'),className + ".java");
                    outPath.getParent().toFile().mkdirs();
                    System.out.println("  " + outPath);
                    Files.write(outPath, outClass.getBytes(StandardCharsets.UTF_8));
                }
            }
        }
    }

    public List<String> convert(String copybookString, String packageName, String rootClassName, String accessor, String charset, String subClassHandling, String wrapperClassName) throws Exception {
        ScriptObjectMirror results = (ScriptObjectMirror) invocable.invokeFunction("convertCopybook", packageName, rootClassName, copybookString, accessor, charset, subClassHandling, wrapperClassName);
        return Arrays.asList(results.values().toArray(new String[results.size()]));
    }

    public List<String> convert(InputStream copybookStream, String packageName, String rootClassName, String accessor, String charset, String subClassHandling, String wrapperClassName) throws Exception {
        return convert(new String(ByteUtils.toByteArray(copybookStream), StandardCharsets.UTF_8), packageName, rootClassName, accessor, charset, subClassHandling, wrapperClassName);