/*
 *******************************************************************************
 * Copyright (C) 2010-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.dev.test.bidi;

import java.io.BufferedReader;
import java.io.IOException;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.lang.UCharacterDirection;
import com.ibm.icu.text.Bidi;
import com.ibm.icu.text.BidiClassifier;

/**
 * @author Markus W. Scherer
 * BiDi conformance test, using the Unicode BidiTest.txt and BidiCharacterTest.txt files.
 * Ported from ICU4C intltest/bidiconf.cpp .
 */
public class BiDiConformanceTest extends TestFmwk {
    public static void main(String[] args) throws Exception {
        new BiDiConformanceTest().run(args);
    }
    public BiDiConformanceTest() {}

    public void TestBidiTest() throws IOException {
        BufferedReader bidiTestFile = TestUtil.getDataReader("unicode/BidiTest.txt");
        try {
            Bidi ubidi = new Bidi();
            ubidi.setCustomClassifier(new ConfTestBidiClassifier());
            lineNumber = 0;
            levelsCount = 0;
            orderingCount = 0;
            errorCount = 0;
outerLoop:
            while (errorCount < 10 && (line = bidiTestFile.readLine()) != null) {
                ++lineNumber;
                lineIndex = 0;
                // Remove trailing comments and whitespace.
                int commentStart = line.indexOf('#');
                if (commentStart >= 0) {
                    line = line.substring(0, commentStart);
                }
                if (!skipWhitespace()) {
                    continue; // Skip empty and comment-only lines.
                }
                if (line.charAt(lineIndex) == '@') {
                    ++lineIndex;
                    if (line.startsWith("Levels:", lineIndex)) {
                        lineIndex += 7;
                        if (!parseLevels(line.substring(lineIndex))) {
                            break;
                        }
                    } else if (line.startsWith("Reorder:", lineIndex)) {
                        lineIndex += 8;
                        if (!parseOrdering(line.substring(lineIndex))) {
                            break;
                        }
                    }
                    // Skip unknown @Xyz: ...
                } else {
                    parseInputStringFromBiDiClasses();
                    if (!skipWhitespace() || line.charAt(lineIndex++) != ';') {
                        errln("missing ; separator on input line " + line);
                        return;
                    }
                    int bitset = Integer.parseInt(line.substring(lineIndex).trim(), 16);
                    // Loop over the bitset.
                    for (int i = 0; i <= 3; ++i) {
                        if ((bitset & (1 << i)) != 0) {
                            ubidi.setPara(inputString, paraLevels[i], null);
                            byte actualLevels[] = ubidi.getLevels();
                            paraLevelName = paraLevelNames[i];
                            if (!checkLevels(actualLevels)) {
                                continue outerLoop;
                            }
                            if (!checkOrdering(ubidi)) {
                                continue outerLoop;
                            }
                        }
                    }
                }
            }
        } finally {
            bidiTestFile.close();
        }
    }

    /*
    *******************************************************************************
    *
    *   created on: 2013jul01
    *   created by: Matitiahu Allouche

    This function performs a conformance test for implementations of the
    Unicode Bidirectional Algorithm, specified in UAX #9: Unicode
    Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/

    Each test case is represented in a single line which is read from a file
    named BidiCharacter.txt.  Empty, blank and comment lines may also appear
    in this file.

    The format of the test data is specified below.  Note that each test
    case constitutes a single line of text; reordering is applied within a
    single line and independently of a rendering engine, and rules L3 and L4
    are out of scope.

    The number sign '#' is the comment character: everything is ignored from
    the occurrence of '#' until the end of the line,
    Empty lines and lines containing only spaces and/or comments are ignored.

    Lines which represent test cases consist of 4 or 5 fields separated by a
    semicolon.  Each field consists of tokens separated by whitespace (space
    or Tab).  Whitespace before and after semicolons is optional.

    Field 0: A sequence of hexadecimal code point values separated by space

    Field 1: A value representing the paragraph direction, as follows:
        - 0 represents left-to-right
        - 1 represents right-to-left
        - 2 represents auto-LTR according to rules P2 and P3 of the algorithm
        - 3 represents auto-RTL according to rules P2 and P3 of the algorithm
        - a negative number whose absolute value is taken as paragraph level;
          this may be useful to test cases where the embedding level approaches
          or exceeds the maximum embedding level.

    Field 2: The resolved paragraph embedding level.  If the input (field 0)
             includes more than one paragraph, this field represents the
             resolved level of the first paragraph.

    Field 3: An ordered list of resulting levels for each token in field 0
             (each token represents one source character).
             The UBA does not assign levels to certain characters (e.g. LRO);
             characters removed in rule X9 are indicated with an 'x'.

    Field 4: An ordered list of indices showing the resulting visual ordering
             from left to right; characters with a resolved level of 'x' are
             skipped.  The number are zero-based.  Each index corresponds to
             a character in the reordered (visual) string. It represents the
             index of the source character in the input (field 0).
             This field is optional.  When it is absent, the visual ordering
             is not verified.

    Examples:

    # This is a comment line.
    L L ON R ; 0 ; 0 ; 0 0 0 1 ; 0 1 2 3
    L L ON R;0;0;0 0 0 1;0 1 2 3

    # Note: in the next line, 'B' represents a block separator, not the letter 'B'.
    LRE A B C PDF;2;0;x 2 0 0 x;1 2 3
    # Note: in the next line, 'b' represents the letter 'b', not a block separator.
    a b c 05d0 05d1 x ; 0 ; 0 ; 0 0 0 1 1 0 ; 0 1 2 4 3 5

    a R R x ; 1 ; 1 ; 2 1 1 2
    L L R R R B R R L L L B ON ON ; 3 ; 0 ; 0 0 1 1 1 0 1 1 2 2 2 1 1 1

    *
    *******************************************************************************
    */
    public void TestBidiCharacterTest() throws IOException {
        BufferedReader bidiTestFile = TestUtil.getDataReader("unicode/BidiCharacterTest.txt");
        try {
            Bidi ubidi = new Bidi();
            lineNumber = 0;
            levelsCount = 0;
            orderingCount = 0;
            errorCount = 0;
outerLoop:
            while (errorCount < 20 && (line = bidiTestFile.readLine()) != null) {
                ++lineNumber;
                paraLevelName = "N/A";
                inputString = "N/A";
                lineIndex = 0;
                // Remove trailing comments and whitespace.
                int commentStart = line.indexOf('#');
                if (commentStart >= 0) {
                    line = line.substring(0, commentStart);
                }
                if (!skipWhitespace()) {
                    continue; // Skip empty and comment-only lines.
                }
                String[] parts = line.split(";");
                if (parts.length < 4) {
                    errorCount++;
                    errln(" on line " + lineNumber + ": Missing ; separator on line: " + line);
                    continue;
                }
                // Parse the code point string in field 0.
                try {
                    inputStringBuilder.delete(0, inputStringBuilder.length());
                    for (String cp : parts[0].trim().split("[ \t]+")) {
                        inputStringBuilder.appendCodePoint(Integer.parseInt(cp, 16));
                    }
                    inputString = inputStringBuilder.toString();
                } catch (Exception e) {
                    errln(" ------------ Invalid string in field 0 on line '" + line + "'");
                    ++errorCount;
                    continue;
                }
                int paraDirection = intFromString(parts[1].trim());
                byte paraLevel;
                if (paraDirection == 0) {
                    paraLevel = 0;
                    paraLevelName = "LTR";
                } else if (paraDirection == 1) {
                    paraLevel = 1;
                    paraLevelName = "RTL";
                } else if (paraDirection == 2) {
                    paraLevel = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
                    paraLevelName = "Auto/LTR";
                } else if (paraDirection == 3) {
                    paraLevel = Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
                    paraLevelName = "Auto/RTL";
                } else if (paraDirection < 0 && -paraDirection <= (Bidi.MAX_EXPLICIT_LEVEL + 1)) {
                    paraLevel = (byte) (-paraDirection);
                    paraLevelName = Byte.toString(paraLevel);
                } else {
                    errorCount++;
                    errln(" on line " + lineNumber + ": Input paragraph direction incorrect at " + line);
                    continue;
                }
                int resolvedParaLevel = intFromString(parts[2].trim());
                if (resolvedParaLevel < 0 || resolvedParaLevel > (Bidi.MAX_EXPLICIT_LEVEL + 1)) {
                    errorCount++;
                    errln(" on line " + lineNumber + ": Resolved paragraph level incorrect at " + line);
                    continue;
                }
                if (!parseLevels(parts[3])) {
                    continue;
                }
                if (parts.length > 4) {
                    if (!parseOrdering(parts[4])) {
                        continue;
                    }
                } else {
                    orderingCount = -1;
                }

                ubidi.setPara(inputString, paraLevel, null);
                byte actualParaLevel = ubidi.getParaLevel();
                if (actualParaLevel != resolvedParaLevel) {
                    errln(" ------------ Wrong resolved paragraph level; expected " + resolvedParaLevel + " actual "
                            + actualParaLevel);
                    printErrorLine();
                }
                byte[] actualLevels = ubidi.getLevels();
                if (!checkLevels(actualLevels)) {
                    continue outerLoop;
                }
                if (!checkOrdering(ubidi)) {
                    continue outerLoop;
                }
            }
        } finally {
            bidiTestFile.close();
        }
    }

    private static final byte paraLevels[]={
        Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT,
        0,
        1,
        Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT
    };
    private static final String paraLevelNames[]={ "auto/LTR", "LTR", "RTL", "auto/RTL" };

    private int intFromString(String str) {
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
            return -9999;
        }
    }

    private boolean parseLevels(String s) {
        directionBits=0;
        levelsCount=0;
        String[] levelStrings=s.trim().split("[ \t]+");
        for(String levelString: levelStrings) {
            if(levelString.length()==0) { continue; }
            if(levelString.equals("x")) {
                levels[levelsCount++]=-1;
            } else {
                try {
                    int value=Integer.parseInt(levelString);
                    if(0<=value && value<=(Bidi.MAX_EXPLICIT_LEVEL+1)) {
                        levels[levelsCount++]=(byte)value;
                        directionBits|=(1<<(value&1));
                        continue;
                    }
                } catch(Exception e) {
                }
                errln(" ------------ Levels parse error at '"+levelString+"'");
                printErrorLine();
                return false;
            }
        }
        return true;
    }
    private boolean parseOrdering(String s) {
        orderingCount=0;
        String[] orderingStrings=s.trim().split("[ \t]+");
        for(String orderingString: orderingStrings) {
            if(orderingString.length()==0) { continue; }
            try {
                int value=Integer.parseInt(orderingString);
                if(value<1000) {
                    ordering[orderingCount++]=value;
                    continue;
                }
            } catch(Exception e) {
            }
            errln(" ------------ Reorder parse error at '"+orderingString+"'");
            printErrorLine();
            return false;
        }
        return true;
    }
    private static char charFromBiDiClass[]={
        0x6c,   // 'l' for L
        0x52,   // 'R' for R
        0x33,   // '3' for EN
        0x2d,   // '-' for ES
        0x25,   // '%' for ET
        0x39,   // '9' for AN
        0x2c,   // ',' for CS
        0x2f,   // '/' for B
        0x5f,   // '_' for S
        0x20,   // ' ' for WS
        0x3d,   // '=' for ON
        0x65,   // 'e' for LRE
        0x6f,   // 'o' for LRO
        0x41,   // 'A' for AL
        0x45,   // 'E' for RLE
        0x4f,   // 'O' for RLO
        0x2a,   // '*' for PDF
        0x60,   // '`' for NSM
        0x7c,   // '|' for BN
        // new in Unicode 6.3/ICU 52
        0x53,   // 'S' for FSI
        0x69,   // 'i' for LRI
        0x49,   // 'I' for RLI
        0x2e    // '.' for PDI
    };
    private class ConfTestBidiClassifier extends BidiClassifier {
        public ConfTestBidiClassifier() {
            super(null);
        }
        @Override
        public int classify(int c) {
            for(int i=0; i<charFromBiDiClass.length; ++i) {
                if(c==charFromBiDiClass[i]) {
                    return i;
                }
            }
            // Character not in our hardcoded table.
            // Should not occur during testing.
            return Bidi.CLASS_DEFAULT;
        }
    }
    private static final int biDiClassNameLengths[]={
        1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 0
    };
    private void parseInputStringFromBiDiClasses() {
        inputStringBuilder.delete(0, 0x7fffffff);
        /*
         * Lengthy but fast BiDi class parser.
         * A simple parser could terminate or extract the name string and use
         *   int32_t biDiClassInt=u_getPropertyValueEnum(UCHAR_BIDI_CLASS, bidiClassString);
         * but that makes this test take significantly more time.
         */
        char c0, c1, c2;
        while(skipWhitespace() && (c0=line.charAt(lineIndex))!=';') {
            int biDiClass=UCharacterDirection.CHAR_DIRECTION_COUNT;
            // Compare each character once until we have a match on
            // a complete, short BiDi class name.
            if(c0=='L') {
                if((lineIndex+2)<line.length() && line.charAt(lineIndex+1)=='R') {
                    c2=line.charAt(lineIndex+2);
                    if(c2=='E') {
                        biDiClass=UCharacterDirection.LEFT_TO_RIGHT_EMBEDDING;
                    } else if(c2=='I') {
                        biDiClass=UCharacterDirection.LEFT_TO_RIGHT_ISOLATE;
                    } else if(c2=='O') {
                        biDiClass=UCharacterDirection.LEFT_TO_RIGHT_OVERRIDE;
                    }
                } else {
                    biDiClass=UCharacterDirection.LEFT_TO_RIGHT;
                }
            } else if(c0=='R') {
                if((lineIndex+2)<line.length() && line.charAt(lineIndex+1)=='L') {
                    c2=line.charAt(lineIndex+2);
                    if(c2=='E') {
                        biDiClass=UCharacterDirection.RIGHT_TO_LEFT_EMBEDDING;
                    } else if(c2=='I') {
                        biDiClass=UCharacterDirection.RIGHT_TO_LEFT_ISOLATE;
                    } else if(c2=='O') {
                        biDiClass=UCharacterDirection.RIGHT_TO_LEFT_OVERRIDE;
                    }
                } else {
                    biDiClass=UCharacterDirection.RIGHT_TO_LEFT;
                }
            } else if(c0=='E') {
                if((lineIndex+1)>=line.length()) {
                    // too short
                } else if((c1=line.charAt(lineIndex+1))=='N') {
                    biDiClass=UCharacterDirection.EUROPEAN_NUMBER;
                } else if(c1=='S') {
                    biDiClass=UCharacterDirection.EUROPEAN_NUMBER_SEPARATOR;
                } else if(c1=='T') {
                    biDiClass=UCharacterDirection.EUROPEAN_NUMBER_TERMINATOR;
                }
            } else if(c0=='A') {
                if((lineIndex+1)>=line.length()) {
                    // too short
                } else if((c1=line.charAt(lineIndex+1))=='L') {
                    biDiClass=UCharacterDirection.RIGHT_TO_LEFT_ARABIC;
                } else if(c1=='N') {
                    biDiClass=UCharacterDirection.ARABIC_NUMBER;
                }
            } else if(c0=='C' && (lineIndex+1)<line.length() && line.charAt(lineIndex+1)=='S') {
                biDiClass=UCharacterDirection.COMMON_NUMBER_SEPARATOR;
            } else if(c0=='B') {
                if((lineIndex+1)<line.length() && line.charAt(lineIndex+1)=='N') {
                    biDiClass=UCharacterDirection.BOUNDARY_NEUTRAL;
                } else {
                    biDiClass=UCharacterDirection.BLOCK_SEPARATOR;
                }
            } else if(c0=='S') {
                biDiClass=UCharacterDirection.SEGMENT_SEPARATOR;
            } else if(c0=='W' && (lineIndex+1)<line.length() && line.charAt(lineIndex+1)=='S') {
                biDiClass=UCharacterDirection.WHITE_SPACE_NEUTRAL;
            } else if(c0=='O' && (lineIndex+1)<line.length() && line.charAt(lineIndex+1)=='N') {
                biDiClass=UCharacterDirection.OTHER_NEUTRAL;
            } else if(c0=='P' && (lineIndex+2)<line.length() && line.charAt(lineIndex+1)=='D') {
                if(line.charAt(lineIndex+2)=='F') {
                    biDiClass=UCharacterDirection.POP_DIRECTIONAL_FORMAT;
                } else if(line.charAt(lineIndex+2)=='I') {
                    biDiClass=UCharacterDirection.POP_DIRECTIONAL_ISOLATE;
                }
            } else if(c0=='N' && (lineIndex+2)<line.length() &&
                      line.charAt(lineIndex+1)=='S' && line.charAt(lineIndex+2)=='M') {
                biDiClass=UCharacterDirection.DIR_NON_SPACING_MARK;
            } else if(c0=='F' && (lineIndex+2)<line.length() &&
                    line.charAt(lineIndex+1)=='S' && line.charAt(lineIndex+2)=='I') {
                biDiClass=UCharacterDirection.FIRST_STRONG_ISOLATE;
            }
            // Now we verify that the class name is terminated properly,
            // and not just the start of a longer word.
            int biDiClassNameLength=biDiClassNameLengths[biDiClass];
            char c;
            if( biDiClass==UCharacterDirection.CHAR_DIRECTION_COUNT ||
                ((lineIndex+biDiClassNameLength)<line.length() &&
                 !isInvWhitespace(c=line.charAt(lineIndex+biDiClassNameLength)) &&
                 c!=';')
            ) {
                throw new IllegalArgumentException(
                    "BiDi class string not recognized at "+line.substring(lineIndex)+" in "+line);
            }
            inputStringBuilder.append(charFromBiDiClass[biDiClass]);
            lineIndex+=biDiClassNameLength;
        }
        inputString=inputStringBuilder.toString();
    }

    private static char printLevel(byte level) {
        if(level<0) {
            return 'x';
        } else {
            return (char)('0'+level);
        }
    }

    private static int getDirectionBits(byte actualLevels[]) {
        int actualDirectionBits=0;
        for(int i=0; i<actualLevels.length; ++i) {
            actualDirectionBits|=(1<<(actualLevels[i]&1));
        }
        return actualDirectionBits;
    }
    private boolean checkLevels(byte actualLevels[]) {
        boolean isOk=true;
        if(levelsCount!=actualLevels.length) {
            errln(" ------------ Wrong number of level values; expected "+levelsCount+" actual "+actualLevels.length);
            isOk=false;
        } else {
            for(int i=0; i<actualLevels.length; ++i) {
                if(levels[i]!=actualLevels[i] && levels[i]>=0) {
                    if(directionBits!=3 && directionBits==getDirectionBits(actualLevels)) {
                        // ICU used a shortcut:
                        // Since the text is unidirectional, it did not store the resolved
                        // levels but just returns all levels as the paragraph level 0 or 1.
                        // The reordering result is the same, so this is fine.
                        break;
                    } else {
                        errln(" ------------ Wrong level value at index "+i+"; expected "+levels[i]+" actual "+actualLevels[i]);
                        isOk=false;
                        break;
                    }
                }
            }
        }
        if(!isOk) {
            printErrorLine();
            StringBuilder els=new StringBuilder("Expected levels:   ");
            int i;
            for(i=0; i<levelsCount; ++i) {
                els.append(' ').append(printLevel(levels[i]));
            }
            StringBuilder als=new StringBuilder("Actual   levels:   ");
            for(i=0; i<actualLevels.length; ++i) {
                als.append(' ').append(printLevel(actualLevels[i]));
            }
            errln(els.toString());
            errln(als.toString());
        }
        return isOk;
    }

    // Note: ubidi_setReorderingOptions(ubidi, UBIDI_OPTION_REMOVE_CONTROLS);
    // does not work for custom BiDi class assignments
    // and anyway also removes LRM/RLM/ZWJ/ZWNJ which is not desirable here.
    // Therefore we just skip the indexes for BiDi controls while comparing
    // with the expected ordering that has them omitted.
    private boolean checkOrdering(Bidi ubidi) {
        if(orderingCount<0)
            return true;
        boolean isOk=true;
        int resultLength=ubidi.getResultLength();  // visual length including BiDi controls
        int i, visualIndex;
        // Note: It should be faster to call ubidi_countRuns()/ubidi_getVisualRun()
        // and loop over each run's indexes, but that seems unnecessary for this test code.
        for(i=visualIndex=0; i<resultLength; ++i) {
            int logicalIndex=ubidi.getLogicalIndex(i);
            if(levels[logicalIndex]<0) {
                continue;  // BiDi control, omitted from expected ordering.
            }
            if(visualIndex<orderingCount && logicalIndex!=ordering[visualIndex]) {
                errln(" ------------ Wrong ordering value at visual index "+visualIndex+"; expected "+
                      ordering[visualIndex]+" actual "+logicalIndex);
                isOk=false;
                break;
            }
            ++visualIndex;
        }
        // visualIndex is now the visual length minus the BiDi controls,
        // which should match the length of the BidiTest.txt ordering.
        if(isOk && orderingCount!=visualIndex) {
            errln(" ------------ Wrong number of ordering values; expected "+orderingCount+" actual "+visualIndex);
            isOk=false;
        }
        if(!isOk) {
            printErrorLine();
            StringBuilder eord=new StringBuilder("Expected ordering: ");
            for(i=0; i<orderingCount; ++i) {
                eord.append(' ').append((char)('0'+ordering[i]));
            }
            StringBuilder aord=new StringBuilder("Actual   ordering: ");
            for(i=0; i<resultLength; ++i) {
                int logicalIndex=ubidi.getLogicalIndex(i);
                if(levels[logicalIndex]<Bidi.LEVEL_DEFAULT_LTR) {
                    aord.append(' ').append((char)('0'+logicalIndex));
                }
            }
            errln(eord.toString());
            errln(aord.toString());
        }
        return isOk;
    }

    private void printErrorLine() {
        ++errorCount;
        errln(String.format("Input line %5d:   %s", lineNumber, line));
        errln("Input string:       "+inputString);
        errln("Para level:         "+paraLevelName);
    }

    private static boolean isInvWhitespace(char c) {
        return ((c)==' ' || (c)=='\t' || (c)=='\r' || (c)=='\n');
    }
    /**
     * Skip isInvWhitespace() characters.
     * @return true if line.charAt[lineIndex] is a non-whitespace, false if lineIndex>=line.length()
     */
    private boolean skipWhitespace() {
        while(lineIndex<line.length()) {
            if(!isInvWhitespace(line.charAt(lineIndex))) {
                return true;
            }
            ++lineIndex;
        }
        return false;
    }

    private String line;
    private int lineIndex;
    private byte levels[]=new byte[1000];  // UBiDiLevel
    private int directionBits;
    private int ordering[]=new int[1000];
    private int lineNumber;
    private int levelsCount;
    private int orderingCount;
    private int errorCount;
    private String inputString;
    private String paraLevelName;
    private StringBuilder inputStringBuilder=new StringBuilder();
}
