// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
**********************************************************************
* Copyright (c) 2002-2009, International Business Machines           *
* Corporation and others.  All Rights Reserved.                      *
**********************************************************************
*/
package com.ibm.icu.dev.test.perf;

import com.ibm.icu.text.Normalizer;

public class NormalizerPerformanceTest extends PerfTest {
    
    String[] NFDFileLines;
    String[] NFCFileLines;
    String[] fileLines;
    
    
    public static void main(String[] args) throws Exception {
        new NormalizerPerformanceTest().run(args);
    }
    
    protected void setup(String[] args) {
        fileLines = readLines(fileName, encoding, bulk_mode);
        NFDFileLines = normalizeInput(fileLines, Normalizer.NFD);
        NFCFileLines = normalizeInput(fileLines, Normalizer.NFC);
    }
    
    // Test NFC Performance
    PerfTest.Function TestICU_NFC_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                    Normalizer.normalize(NFDFileLines[i], Normalizer.NFC);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestICU_NFC_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                    Normalizer.normalize(NFCFileLines[i], Normalizer.NFC);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestICU_NFC_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.normalize(fileLines[i], Normalizer.NFC);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    // Test NFD Performance
    PerfTest.Function TestICU_NFD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                    Normalizer.normalize(NFDFileLines[i], Normalizer.NFD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestICU_NFD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                    Normalizer.normalize(NFCFileLines[i], Normalizer.NFD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestICU_NFD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.normalize(fileLines[i], Normalizer.NFD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }

    // Test NFC Performance
    PerfTest.Function TestJDK_NFC_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++)
                    normalizerTest(NFDFileLines[i], true);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++)
                    totalChars = totalChars + NFDFileLines[i].length();
                return totalChars;
            }
        };
    }
  
    PerfTest.Function TestJDK_NFC_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++)
                    normalizerTest(NFCFileLines[i], true);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++)
                    totalChars = totalChars + NFCFileLines[i].length();
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestJDK_NFC_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++)
                    normalizerTest(fileLines[i], true);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++)
                    totalChars = totalChars + fileLines[i].length();
                return totalChars;
            }
        };
    }
    
    // Test NFD Performance
    PerfTest.Function TestJDK_NFD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++)
                    normalizerTest(NFDFileLines[i], false);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++)
                    totalChars = totalChars + NFDFileLines[i].length();
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestJDK_NFD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++)
                    normalizerTest(NFCFileLines[i], false);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++)
                    totalChars = totalChars + NFCFileLines[i].length();
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestJDK_NFD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++)
                    normalizerTest(fileLines[i], false);
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++)
                    totalChars = totalChars + fileLines[i].length();
                return totalChars;
            }
        };
    }
    // Test FCD Performance
    PerfTest.Function TestICU_FCD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                    Normalizer.normalize(NFDFileLines[i], Normalizer.FCD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }

    PerfTest.Function TestICU_FCD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                    Normalizer.normalize(NFCFileLines[i], Normalizer.FCD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestICU_FCD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.normalize(fileLines[i], Normalizer.FCD);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    // Test Quick Check Performance
    PerfTest.Function TestQC_NFC_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                    Normalizer.quickCheck(NFDFileLines[i], Normalizer.NFC,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_NFC_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                    Normalizer.quickCheck(NFCFileLines[i], Normalizer.NFC,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_NFC_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.quickCheck(fileLines[i], Normalizer.NFC,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_NFD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                    Normalizer.quickCheck(NFDFileLines[i], Normalizer.NFD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_NFD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                     Normalizer.quickCheck(NFCFileLines[i], Normalizer.NFD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_NFD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                     Normalizer.quickCheck(fileLines[i], Normalizer.NFD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_FCD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                     Normalizer.quickCheck(NFDFileLines[i], Normalizer.FCD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_FCD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                     Normalizer.quickCheck(NFCFileLines[i], Normalizer.FCD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestQC_FCD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                     Normalizer.quickCheck(fileLines[i], Normalizer.FCD,0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    // Test isNormalized Performance
    PerfTest.Function TestIsNormalized_NFC_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                     Normalizer.isNormalized(NFDFileLines[i], Normalizer.NFC, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_NFC_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                    Normalizer.isNormalized(NFCFileLines[i], Normalizer.NFC, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_NFC_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.isNormalized(fileLines[i], Normalizer.NFC, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_NFD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                     Normalizer.isNormalized(NFDFileLines[i], Normalizer.NFD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_NFD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                     Normalizer.isNormalized(NFCFileLines[i], Normalizer.NFD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_NFD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                    Normalizer.isNormalized(fileLines[i], Normalizer.NFD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_FCD_NFD_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFDFileLines.length; i++) {
                     Normalizer.isNormalized(NFDFileLines[i], Normalizer.FCD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFDFileLines.length; i++) {
                    totalChars = totalChars + NFDFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_FCD_NFC_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < NFCFileLines.length; i++) {
                     Normalizer.isNormalized(NFCFileLines[i], Normalizer.FCD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < NFCFileLines.length; i++) {
                    totalChars = totalChars + NFCFileLines[i].length();
                }
                return totalChars;
            }
        };
    }
    
    PerfTest.Function TestIsNormalized_FCD_Orig_Text() {
        return new PerfTest.Function() {
            public void call() {
                for (int i = 0; i < fileLines.length; i++) {
                     Normalizer.isNormalized(fileLines[i], Normalizer.FCD, 0);
                }
            }
            
            public long getOperationsPerIteration() {
                int totalChars = 0;
                for (int i = 0; i < fileLines.length; i++) {
                    totalChars = totalChars + fileLines[i].length();
                }
                return totalChars;
            }
        };
    }
      
    /*
      private void printUsage() {
        System.out.println("Usage: " + this.getClass().getName() + " [OPTIONS] fileName\n"
                            + "\t-f or --fileName  \tfile to be used as test data\n"
                            + "\t-s or --sourceDir \tsource directory for files followed by path\n"
                            + "\t-e or --encoding  \tencoding of source files\n"
                            + "\t-b or --bulkMode  \tnormalize whole file at once\n"
                            + "\t-l or --lineMode  \tnormalize file one line at a time\n"
            );
        System.exit(1);
    }
    */
    
    String[] normalizeInput(String[] src, Normalizer.Mode mode) {
        String[] dest = new String[src.length];
        for (int i = 0; i < src.length; i++) {
            dest[i] = Normalizer.normalize(src[i], mode);
        }
        
        return dest;
    }
    
    /*
    void normalizerInit(boolean compose) {
        Class normalizer;
        boolean sun;
        
        try {
            normalizer = Class.forName("java.text.Normalizer");
            sun = false;
        } catch (ClassNotFoundException ex) {
            try {
                normalizer = Class.forName("sun.text.Normalizer");
                sun = true;
            } catch (ClassNotFoundException ex2) {
                throw new RuntimeException(
                        "Could not find sun.text.Normalizer nor java.text.Normalizer and their required subclasses");
            }
        }
        
        try {
            if (sun) {
                normalizerArgs = new Object[] { null, null, new Integer(0) };
                normalizerArgs[1] = normalizer.getField(compose ? "COMPOSE" : "DECOMP").get(null);
                normalizerMethod = normalizer.getMethod("normalize", new Class[] { String.class, normalizerArgs[1].getClass(), int.class });
                // sun.text.Normalizer.normalize(line, compose
                //   ? sun.text.Normalizer.COMPOSE
                //   : sun.text.Normalizer.DECOMP, 0);
            } else {
                normalizerArgs = new Object[] { null, null };
                normalizerArgs[1] = Class.forName("java.text.Normalizer$Form").getField(compose ? "NFC" : "NFD").get(null);
                normalizerMethod = normalizer.getMethod("normalize", new Class[] { CharSequence.class, normalizerArgs[1].getClass()});
                // java.text.Normalizer.normalize(line, compose
                //   ? java.text.Normalizer.Form.NFC
                //   : java.text.Normalizer.Form.NFD);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("Reflection error -- could not load the JDK normalizer (" + normalizer.getName() + ")");
        }
    }
    
    void normalizerTest(String line) {
        try {
            normalizerArgs[0] = line;
            normalizerMethod.invoke(line, normalizerArgs);
        } catch (Exception ex) {
            if (ex instanceof InvocationTargetException) {
                Throwable cause = ex.getCause();
                cause.printStackTrace();
                throw new RuntimeException(cause.getMessage());
            } else {
                throw new RuntimeException("Reflection error -- could not run the JDK normalizer");
            }
        }
    }
    */

    void normalizerTest(String line, boolean compose) {
//        sun.text.Normalizer.normalize(line, compose
//            ? sun.text.Normalizer.COMPOSE
//            : sun.text.Normalizer.DECOMP, 0);
        java.text.Normalizer.normalize(line, compose
            ? java.text.Normalizer.Form.NFC
            : java.text.Normalizer.Form.NFD);
    }
}
