/*
 * (C) Copyright IBM Corp. 1998-2004.  All Rights Reserved.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */
package com.ibm.richtext.test.unit;

import com.ibm.icu.dev.test.TestFmwk;

import com.ibm.richtext.textlayout.attributes.AttributeMap;
import com.ibm.richtext.textlayout.attributes.TextAttribute;

import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.StyleModifier;

import java.text.CharacterIterator;
import java.util.Random;

import java.io.*;

public class TestMText extends TestFmwk {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
    public static void main(String[] args) throws Exception {

        new TestMText().run(args);
    }
    
    private static final int TEST_ITERATIONS = 5000;
    private static final int STYLE_TEST_ITERATIONS = 5000;
    private static final long RAND_SEED = 598436;

    private static final int NOT_IN_MONKEY_TEST = -5000;
    private int testIteration = NOT_IN_MONKEY_TEST;
    private int theCase = NOT_IN_MONKEY_TEST;
    
    private static StyleModifier createMinusModifier(final Object attr) {
        return new StyleModifier() {
            public AttributeMap modifyStyle(AttributeMap style) {
                return style.removeAttribute(attr);
            }
        };
    }

    public void test() {
    
        simpleTest();
        styleTest();
        monkeyTest(true);
    }
    
    public void simpleTest() {

        AttributeMap boldStyle = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
        AttributeMap italicStyle = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);

        MConstText allBold = new StyledText("bbbbb", boldStyle);
        MConstText allItalic = new StyledText("iii", italicStyle);
        MConstText plain = new StyledText("pppppp", AttributeMap.EMPTY_ATTRIBUTE_MAP);

        {
            MText buf = new StyledText();
            int ts = buf.getTimeStamp();
            buf.append(allBold);
            buf.append(allItalic);

            if (ts == buf.getTimeStamp()) {
                errln("Time stamp not incremented");
            }

            // should be bbbbbiii now

            if (buf.length() != allBold.length() + allItalic.length()) {
                errln("Length is wrong.");
            }

            for (int i=0; i < buf.length(); i++) {

                char rightChar;
                AttributeMap rightStyle;

                if (i < allBold.length()) {
                    rightChar = allBold.at(0);
                    rightStyle = boldStyle;
                }
                else {
                    rightChar = allItalic.at(0);
                    rightStyle = italicStyle;
                }

                if (buf.at(i) != rightChar) {
                    errln("Character is wrong.");
                }
                if (!buf.characterStyleAt(i).equals(rightStyle)) {
                    errln("Style is wrong.");
                }
            }

            int pos = 0;

            if (!buf.characterStyleAt(pos).equals(boldStyle)) {
                errln("First style is wrong.");
            }
            if (buf.characterStyleLimit(pos) != allBold.length()) {
                errln("Run length is wrong.");
            }

            pos = allBold.length();

            if (!buf.characterStyleAt(pos).equals(italicStyle)) {
                errln("Second style is wrong.");
            }
            if (buf.characterStyleLimit(pos) != buf.length()) {
                errln("Run length is wrong.");
            }

            {
                buf.resetDamagedRange();
                int oldLength = buf.length();
                buf.replace(buf.length(), buf.length(), allBold, 0, allBold.length());
                // bbbbbiiibbbbb

                if (buf.damagedRangeStart() != oldLength) {
                    errln("Damaged range start is incorrect");
                }
                if (buf.damagedRangeLimit() != buf.length()) {
                    errln("Damaged range limit is incorrect");
                }
            }

            int start = allBold.length();
            int limit = start + allItalic.length();
            buf.remove(start, limit);
            // bbbbbbbbbb

            if (buf.length() != 2 * allBold.length()) {
                errln("Text should be twice the length of bold text.");
            }

            pos = buf.length() / 2;
            if (buf.characterStyleStart(pos) != 0 ||
                            buf.characterStyleLimit(pos) != buf.length()) {
                errln("Run range is wrong.");
            }
            if (!buf.characterStyleAt(pos).equals(boldStyle)) {
                errln("Run style is wrong.");
            }

            ts = buf.getTimeStamp();
            CharacterIterator cIter = buf.createCharacterIterator();
            for (char ch = cIter.first(); ch != CharacterIterator.DONE; ch = cIter.next()) {
                if (ch != allBold.at(0)) {
                    errln("Character is wrong.");
                }
            }

            if (ts != buf.getTimeStamp()) {
                errln("Time stamp should not have changed");
            }

            buf.replace(0, 1, plain, 0, plain.length());

            if (ts == buf.getTimeStamp()) {
                errln("Time stamp not incremented");
            }

            // ppppppbbbbbbbbb
            buf.replace(plain.length(), buf.length(), allItalic, 0, allItalic.length());
            // ppppppiii

            if (buf.length() != allItalic.length()+plain.length()) {
                errln("Length is wrong.");
            }

            pos = 0;
            if (buf.characterStyleLimit(pos) != plain.length()) {
                errln("Run limit is wrong.");
            }

            pos = plain.length();
            if (buf.characterStyleLimit(pos) != buf.length()) {
                errln("Run limit is wrong.");
            }

            buf.replace(plain.length(), plain.length(), allBold, 0, allBold.length());
            // ppppppbbbbbiii

            AttributeMap st = buf.characterStyleAt(1);
            if (!st.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
                errln("Style is wrong.");
            }
            if (buf.characterStyleStart(1) != 0 || buf.characterStyleLimit(1) != plain.length()) {
                errln("Style start is wrong.");
            }

            st = buf.characterStyleAt(buf.length() - 1);
            if (!st.equals(italicStyle)) {
                errln("Style is wrong.");
            }
            if (buf.characterStyleStart(buf.length() - 1) != plain.length()+allBold.length()) {
                errln("Style start is wrong.");
            }

            if (buf.characterStyleLimit(buf.length() - 1) != buf.length()) {
                errln("Style limit is wrong.");
            }
        }
    }

    private static int randInt(Random rand, int limit) {

        return randInt(rand, 0, limit);
    }

    private static int randInt(Random rand, int start, int limit) {

        if (start > limit) {
            throw new IllegalArgumentException("Range length is negative.");
        }
        else if (start == limit) {
            return start;
        }

        return start + (Math.abs(rand.nextInt())%(limit-start)) ;
    }

    public void styleTest() {

        MText text = new StyledText("0123456789", AttributeMap.EMPTY_ATTRIBUTE_MAP);

        AttributeMap[] styles = new AttributeMap[text.length()];
        for (int i=0; i < styles.length; i++) {
            styles[i] = AttributeMap.EMPTY_ATTRIBUTE_MAP;
        }
        AttributeMap[] oldStyles = new AttributeMap[styles.length];
        System.arraycopy(styles, 0, oldStyles, 0, styles.length);

        AttributeMap bigStyle = new AttributeMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).
                                                    addAttribute(TextAttribute.SIZE, new Float(23.0f));

        StyleModifier[] modifiers = {
            StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)),
            StyleModifier.createAddModifier(new AttributeMap(TextAttribute.WEIGHT, new Float(1.0f))),
            createMinusModifier(TextAttribute.WEIGHT),

            StyleModifier.createAddModifier(new AttributeMap(TextAttribute.POSTURE, new Float(0.0f))),
            StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)),
            createMinusModifier(TextAttribute.POSTURE),

            StyleModifier.createAddModifier(bigStyle),
            StyleModifier.createReplaceModifier(bigStyle),
            createMinusModifier(bigStyle.getKeySet())
        };

        Random rand = new Random(RAND_SEED);
        final int stopAt = 4;

        for (int testIteration=0; testIteration < STYLE_TEST_ITERATIONS + 1; testIteration++) {

            System.arraycopy(styles, 0, oldStyles, 0, styles.length);

            int startingAt = Integer.MAX_VALUE;
            int endingAt = Integer.MIN_VALUE;
            int oldTs = text.getTimeStamp();

            // hack way to do an invariant check before starting...
            if (testIteration != 0) {
                // modify styles
                text.resetDamagedRange();
                startingAt = randInt(rand, styles.length+1);
                endingAt = randInt(rand, startingAt, styles.length+1);
                StyleModifier modifier = modifiers[randInt(rand, modifiers.length)];

                if (testIteration == stopAt) {
                    testIteration = stopAt;
                }
                text.modifyCharacterStyles(startingAt, endingAt, modifier);

                for (int j=startingAt; j < endingAt; j++) {
                    styles[j] = modifier.modifyStyle(styles[j]);
                }
            }

            // check invariants
            AttributeMap oldStyle = null;
            int textLength = text.length();
            for (int runStart = 0; runStart < textLength;) {

                AttributeMap currentStyle = text.characterStyleAt(runStart);
                int runLimit = text.characterStyleLimit(runStart);
                if (runStart >= runLimit) {
                    errln("Run length is not positive");
                }
                if (currentStyle.equals(oldStyle)) {
                    errln("Styles didn't merge");
                }

                for (int pos=runStart; pos < runLimit; pos++) {
                    AttributeMap charStyleAtPos = text.characterStyleAt(pos);
                    if (currentStyle != charStyleAtPos) {
                        errln("Iterator style is not equal to text style at " + pos + ".");
                    }
                    AttributeMap expected = styles[pos];
                    if (!currentStyle.equals(expected)) {
                        errln("Iterator style doesn't match expected style at " + pos + ".");
                    }
                    if (!(text.characterStyleStart(pos) == runStart) ||
                            !(text.characterStyleLimit(pos) == runLimit)) {
                        errln("style run start / limit is not consistent");
                    }
                }
                runStart = runLimit;
            }
            if (textLength > 0) {
                if (text.characterStyleAt(textLength) !=
                            text.characterStyleAt(textLength-1)) {
                    errln("Character styles at end aren't the same");
                }
            }

            // check damaged range:
            int damageStart = Integer.MAX_VALUE;
            int damageLimit = Integer.MIN_VALUE;
            for (int i=0; i < textLength; i++) {
                if (!styles[i].equals(oldStyles[i])) {
                    damageStart = Math.min(i, damageStart);
                    damageLimit = Math.max(i+1, damageLimit);
                }
            }
            if (damageStart != text.damagedRangeStart() ||
                            damageLimit != text.damagedRangeLimit()) {
                logln("Test iteration: " + testIteration);
                logln("startingAt: " + startingAt + ";  endingAt: " + endingAt);
                logln("damageStart: " + damageStart + ";  damageLimit: " + damageLimit);
                logln("text.rangeStart: " + text.damagedRangeStart() +
                                   "text.rangeLimit: " + text.damagedRangeLimit());
                errln("Damage range start or limit is not expected value");
            }

            if ((damageLimit == Integer.MIN_VALUE) != (oldTs == text.getTimeStamp())) {

                errln("timeStamp is incorrect");
            }
        }
    }

    public void msg(String message, int level, boolean incCount, boolean newln) {
        if (level == ERR && testIteration != NOT_IN_MONKEY_TEST) {
            message = "testIteration="+testIteration+"; testCase="+theCase+message;
        }
        super.msg(message, level, incCount, newln);
    }
    
    /**
    * Perform a random series of operations on an MText and
    * check the result of each operation against a set of invariants.
    */
    public void monkeyTest(boolean streaming) {

        /*
            You can add any operation to the switch statement provided it
            preserves the following invariants:
            - The String plainText contains the same text as the StyledStringBuffer.
              Obviously, for the test to be meaningful plainText must be computed
              independently of the buffer (ie don't write:  plainText = buf.getStyledString().toString()).
            - Every 'b' is bold, every 'i' is italic, every 'p' is plain, and
              no other characters appear in the text.
        */

        AttributeMap boldAttrs = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
        AttributeMap italicAttrs = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
        AttributeMap emptyAttrs = AttributeMap.EMPTY_ATTRIBUTE_MAP;

        final String bold1Str_getString = "b";
        MConstText bold1Str = new StyledText(bold1Str_getString, boldAttrs);

        final String italic1Str_getString = "i";
        MConstText italic1Str = new StyledText(italic1Str_getString, italicAttrs);

        final String plain1Str_getString = "p";
        MConstText plain1Str = new StyledText(plain1Str_getString, emptyAttrs);

        StyledText temp = new StyledText();
        temp.append(bold1Str);
        temp.append(italic1Str);
        final String boldItalicStr_getString = bold1Str_getString.concat(italic1Str_getString);
        MConstText boldItalicStr = temp;

        temp = new StyledText();
        temp.append(bold1Str);
        temp.append(bold1Str);
        temp.append(bold1Str);
        final String bold3Str_getString = "bbb";
        MConstText bold3Str = temp;

        MText buf = new StyledText();
        String plainText = new String();
        //int testIteration=0; - now instance variables so errln can report it
        //int theCase=0;

        final int NUM_CASES = 14;
        boolean[] casesExecuted = new boolean[NUM_CASES];
        final int stopAt = -1;
        Random rand = new Random(RAND_SEED);

        final String ALWAYS_DIFFERENT = "\uFEFF";

            for (testIteration=0; testIteration < TEST_ITERATIONS; testIteration++) {

                theCase = randInt(rand, NUM_CASES);

                casesExecuted[theCase] = true;

                if (testIteration == stopAt) {
                    testIteration = stopAt;  // Convenient place to put breakpoint
                }

                int timeStamp = buf.getTimeStamp();
                String oldPlainText = plainText;
                if (oldPlainText == null) {
                    errln("oldPlainText is null!");
                }

                switch (theCase) {

                    case 0:
                        // create new string; replace chars at start with different style
                        buf = new StyledText();
                        buf.append(bold3Str);
                        buf.replace(0, 1, italic1Str, 0, italic1Str.length());
                        buf.replace(0, 0, italic1Str, 0, italic1Str.length());

                        plainText = bold3Str_getString.substring(1, bold3Str.length());
                        plainText = italic1Str_getString.concat(plainText);
                        plainText = italic1Str_getString.concat(plainText);
                        oldPlainText = null;
                        break;

                    case 1:
                        // delete the last character from the string
                        if (buf.length() == 0) {
                            buf.replace(0, 0, italic1Str, 0, italic1Str.length());
                            plainText = italic1Str_getString;
                            oldPlainText = ALWAYS_DIFFERENT;
                        }
                        buf.remove(buf.length()-1, buf.length());
                        plainText = plainText.substring(0, plainText.length()-1);
                        break;

                    case 2:
                        // replace some of the buffer with boldItalicStr
                        int rStart = randInt(rand, buf.length()+1);
                        int rStop = randInt(rand, rStart, buf.length()+1);
                        buf.replace(rStart, rStop, boldItalicStr);
                        {
                            String newString = (rStart>0)? plainText.substring(0, rStart) : new String();
                            newString = newString.concat(boldItalicStr_getString);
                            if (rStop < plainText.length())
                                newString = newString.concat(plainText.substring(rStop, plainText.length()));
                            oldPlainText = ALWAYS_DIFFERENT;
                            plainText = newString;
                        }
                        break;

                    case 3:
                        // repeatedly insert strings into the center of the buffer
                        {
                            int insPos = buf.length() / 2;
                            String prefix = plainText.substring(0, insPos);
                            String suffix = plainText.substring(insPos, plainText.length());
                            String middle = new String();
                            for (int ii=0; ii<4; ii++) {
                                MConstText which = (ii%2==0)? boldItalicStr : bold3Str;
                                String whichString = (ii%2==0)? boldItalicStr_getString : bold3Str_getString;
                                int tempPos = insPos+middle.length();
                                buf.insert(tempPos, which);
                                middle = middle.concat(whichString);
                            }
                            plainText = prefix.concat(middle).concat(suffix);
                            oldPlainText = ALWAYS_DIFFERENT;
                        }
                        break;

                    case 4:
                    // insert bold1Str at end
                        buf.append(bold1Str);
                        plainText = plainText.concat(bold1Str_getString);
                        break;

                    case 5:
                    // delete a character from the string
                        if (buf.length() > 0) {
                            int delPos = randInt(rand, buf.length()-1);
                            buf.remove(delPos, delPos+1);
                            plainText = plainText.substring(0, delPos).concat(plainText.substring(delPos+1));
                        }
                        else {
                            buf.replace(0, 0, plain1Str, 0, plain1Str.length());
                            plainText = plain1Str_getString;
                        }
                        break;

                    case 6:
                    // replace the contents of the buffer (except the first character) with itself
                        {
                            int start = buf.length() > 1? 1 : 0;
                            buf.replace(start, buf.length(), buf);
                            plainText = plainText.substring(0, start).concat(plainText);
                            if (buf.length() > 0) {
                                oldPlainText = ALWAYS_DIFFERENT;
                            }
                        }
                        break;

                    case 7:
                    // append the contents of the buffer to itself
                        {
                            MConstText content = buf;
                            buf.insert(buf.length(), content);
                            plainText = plainText.concat(plainText);
                        }
                        break;

                    case 8:
                    // replace the buffer with boldItalicStr+bold3Str
                        {
                            MText replacement = new StyledText();
                            replacement.append(boldItalicStr);
                            replacement.append(bold3Str);
                            buf.replace(0, buf.length(), replacement, 0, replacement.length());
                            plainText = boldItalicStr_getString.concat(bold3Str_getString);
                            oldPlainText = ALWAYS_DIFFERENT;
                        }
                        break;

                    case 9:
                    // insert bold1Str at end - same as 4 but uses different API
                        buf.replace(buf.length(),
                                    buf.length(),
                                    bold1Str_getString.toCharArray(),
                                    0,
                                    bold1Str_getString.length(),
                                    boldAttrs);
                        plainText = plainText.concat(bold1Str_getString);
                        break;

                    case 10:
                    // remove all
                        buf.remove();
                        plainText = "";
                        oldPlainText = ALWAYS_DIFFERENT;
                        break;

                    case 11:
                    // remove all - different way
                        buf.remove(0, buf.length());
                        plainText = "";
                        break;

                    case 12:
                        // insert 'i' at 3rd character (or last, if fewer than 3 chars)
                        {
                            int insPos = Math.min(buf.length(), 3);
                            buf.replace(insPos, insPos, 'i', italicAttrs);
                            plainText = (plainText.substring(0, insPos)).
                                        concat(italic1Str_getString).
                                        concat(plainText.substring(insPos));
                        }
                        break;

                    case 13:
                        if (streaming) {
                            Throwable error = null;
                            try {
                                ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
                                ObjectOutputStream objOut = new ObjectOutputStream(bytesOut);
                                objOut.writeObject(buf);

                                ByteArrayInputStream bytesIn =
                                                new ByteArrayInputStream(bytesOut.toByteArray());
                                ObjectInputStream objIn = new ObjectInputStream(bytesIn);
                                buf = (MText) objIn.readObject();
                                oldPlainText = null;
                            }
                            catch(IOException e) {
                                error = e;
                            }
                            catch(ClassNotFoundException e) {
                                error = e;
                            }
                            if (error != null) {
                                error.printStackTrace();
                                errln("Streaming problem: " + error);
                            }
                        }
                        break;

                    default:
                        errln("Invalid case.");
                }

                // Check time stamp if oldPlainText != null.
                // Time stamp should be different iff
                // oldPlainText == plainText
                if (oldPlainText != null) {
                    if ((timeStamp==buf.getTimeStamp()) !=
                                    oldPlainText.equals(plainText)) {
                        logln("plainText hashCode: " + plainText.hashCode());
                        logln("oldPlainText hashCode: " + oldPlainText.hashCode());
                        errln("Time stamp is incorrect");
                    }
                }

                // now check invariants:
                if (plainText.length() != buf.length()) {
                    errln("Lengths don't match");
                }

                for (int j=0; j < buf.length(); j++) {
                    if (buf.at(j) != plainText.charAt(j)) {
                        errln("Characters don't match.");
                    }
                }

                int start;
                for (start = 0; start < buf.length();) {

                    if (start != buf.characterStyleStart(start)) {
                        errln("style start is wrong");
                    }
                    int limit = buf.characterStyleLimit(start);
                    if (start >= limit) {
                        errln("start >= limit");
                    }
                    char current = plainText.charAt(start);

                    AttributeMap comp = null;
                    if (current == 'p') {
                        comp = emptyAttrs;
                    }
                    else if (current == 'b') {
                        comp = boldAttrs;
                    }
                    else if (current == 'i') {
                        comp = italicAttrs;
                    }
                    else {
                        errln("An invalid character snuck in!");
                    }

                    AttributeMap startStyle = buf.characterStyleAt(start);
                    if (!comp.equals(startStyle)) {
                        errln("Style is not expected style.");
                    }

                    for (int j = start; j < limit; j++) {
                        if (plainText.charAt(j) != current) {
                            errln("Character doesn't match style.");
                        }
                        if (buf.characterStyleAt(j) != startStyle) {
                            errln("Incorrect style in run");
                        }
                    }

                    if (limit < buf.length()) {
                        if (plainText.charAt(limit) == current) {
                            errln("Style run ends too soon.");
                        }
                    }
                    start = limit;
                }
                if (start != buf.length()) {
                    errln("Last limit is not buffer length.");
                }

                // won't try to compute and check damaged range;  however,
                // if nonempty it should always be within text
                int damageStart = buf.damagedRangeStart();
                int damageLimit = buf.damagedRangeLimit();
                if (damageStart == Integer.MAX_VALUE) {
                    if (damageLimit != Integer.MIN_VALUE) {
                        errln("Invalid empty interval");
                    }
                }
                else {
                    if (damageStart > damageLimit) {
                        errln("Damage range inverted");
                    }
                    if (damageStart < 0 || damageLimit > buf.length()) {
                        errln("Damage range endpoint out of bounds");
                    }
                }
            }

        testIteration = NOT_IN_MONKEY_TEST;
        
        boolean allCasesExecuted = true;
        for (int index=0; index < NUM_CASES; index++) {
            allCasesExecuted &= casesExecuted[index];
            if (casesExecuted[index] == false) {
                logln("Case " + index + " not executed.");
            }
        }
        //if (allCasesExecuted) {
        //    logln("All cases executed.");
        //}
    }
}
