/*
*******************************************************************************
*   Copyright (C) 2011, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*   created on: 2011aug12
*   created by: Markus W. Scherer
*/

package com.ibm.icu.dev.test.format;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.ibm.icu.text.MessagePattern;
import com.ibm.icu.text.MessagePatternUtil;
import com.ibm.icu.text.MessagePatternUtil.ArgNode;
import com.ibm.icu.text.MessagePatternUtil.ComplexArgStyleNode;
import com.ibm.icu.text.MessagePatternUtil.MessageContentsNode;
import com.ibm.icu.text.MessagePatternUtil.MessageNode;
import com.ibm.icu.text.MessagePatternUtil.TextNode;
import com.ibm.icu.text.MessagePatternUtil.VariantNode;

/**
 * Test MessagePatternUtil (MessagePattern-as-tree-of-nodes API)
 * by building parallel trees of nodes and verifying that they match.
 */
public final class MessagePatternUtilTest extends com.ibm.icu.dev.test.TestFmwk {
    public static void main(String[] args) throws Exception {
        new MessagePatternUtilTest().run(args);
    }

    // The following nested "Expect..." classes are used to build
    // a tree structure parallel to what the MessagePatternUtil class builds.
    // These nested test classes are not static so that they have access to TestFmwk methods.

    private class ExpectMessageNode {
        private ExpectMessageNode expectTextThatContains(String s) {
            contents.add(new ExpectTextNode(s));
            return this;
        }
        private ExpectMessageNode expectReplaceNumber() {
            contents.add(new ExpectMessageContentsNode());
            return this;
        }
        private ExpectMessageNode expectNoneArg(Object name) {
            contents.add(new ExpectArgNode(name));
            return this;
        }
        private ExpectMessageNode expectSimpleArg(Object name, String type) {
            contents.add(new ExpectArgNode(name, type));
            return this;
        }
        private ExpectMessageNode expectSimpleArg(Object name, String type, String style) {
            contents.add(new ExpectArgNode(name, type, style));
            return this;
        }
        private ExpectComplexArgNode expectChoiceArg(Object name) {
            return expectComplexArg(name, MessagePattern.ArgType.CHOICE);
        }
        private ExpectComplexArgNode expectPluralArg(Object name) {
            return expectComplexArg(name, MessagePattern.ArgType.PLURAL);
        }
        private ExpectComplexArgNode expectSelectArg(Object name) {
            return expectComplexArg(name, MessagePattern.ArgType.SELECT);
        }
        private ExpectComplexArgNode expectComplexArg(Object name, MessagePattern.ArgType argType) {
            ExpectComplexArgNode complexArg = new ExpectComplexArgNode(this, name, argType);
            contents.add(complexArg);
            return complexArg;
        }
        private ExpectComplexArgNode finishVariant() {
            return parent;
        }
        private void checkMatches(MessageNode msg) {
            // matches() prints all errors.
            matches(msg);
        }
        private boolean matches(MessageNode msg) {
            List<MessageContentsNode> msgContents = msg.getContents();
            boolean ok = assertEquals("different numbers of MessageContentsNode",
                                      contents.size(), msgContents.size());
            if (ok) {
                Iterator<MessageContentsNode> msgIter = msgContents.iterator();
                for (ExpectMessageContentsNode ec : contents) {
                    ok &= ec.matches(msgIter.next());
                }
            }
            if (!ok) {
                errln("error in message: " + msg.toString());
            }
            return ok;
        }
        private ExpectComplexArgNode parent;  // for finishVariant()
        private List<ExpectMessageContentsNode> contents =
            new ArrayList<ExpectMessageContentsNode>();
    }

    /**
     * Base class for message contents nodes.
     * Used directly for REPLACE_NUMBER nodes, subclassed for others.
     */
    private class ExpectMessageContentsNode {
        protected boolean matches(MessageContentsNode c) {
            return assertEquals("not a REPLACE_NUMBER node",
                                MessageContentsNode.Type.REPLACE_NUMBER, c.getType());
        }
    }

    private class ExpectTextNode extends ExpectMessageContentsNode {
        private ExpectTextNode(String subString) {
            this.subString = subString;
        }
        @Override
        protected boolean matches(MessageContentsNode c) {
            return
                assertEquals("not a TextNode",
                             MessageContentsNode.Type.TEXT, c.getType()) &&
                assertTrue("TextNode does not contain \"" + subString + "\"",
                           ((TextNode)c).getText().contains(subString));
        }
        private String subString;
    }

    private class ExpectArgNode extends ExpectMessageContentsNode {
        private ExpectArgNode(Object name) {
            this(name, null, null);
        }
        private ExpectArgNode(Object name, String type) {
            this(name, type, null);
        }
        private ExpectArgNode(Object name, String type, String style) {
            if (name instanceof String) {
                this.name = (String)name;
                this.number = -1;
            } else {
                this.number = (Integer)name;
                this.name = Integer.toString(this.number);
            }
            if (type == null) {
                argType = MessagePattern.ArgType.NONE;
            } else {
                argType = MessagePattern.ArgType.SIMPLE;
            }
            this.type = type;
            this.style = style;
        }
        @Override
        protected boolean matches(MessageContentsNode c) {
            boolean ok =
                assertEquals("not an ArgNode",
                             MessageContentsNode.Type.ARG, c.getType());
            if (!ok) {
                return ok;
            }
            ArgNode arg = (ArgNode)c;
            ok &= assertEquals("unexpected ArgNode argType",
                               argType, arg.getArgType());
            ok &= assertEquals("unexpected ArgNode arg name",
                               name, arg.getName());
            ok &= assertEquals("unexpected ArgNode arg number",
                               number, arg.getNumber());
            ok &= assertEquals("unexpected ArgNode arg type name",
                               type, arg.getTypeName());
            ok &= assertEquals("unexpected ArgNode arg style",
                               style, arg.getSimpleStyle());
            if (argType == MessagePattern.ArgType.NONE || argType == MessagePattern.ArgType.SIMPLE) {
                ok &= assertNull("unexpected non-null complex style", arg.getComplexStyle());
            }
            return ok;
        }
        private String name;
        private int number;
        protected MessagePattern.ArgType argType;
        private String type;
        private String style;
    }

    private class ExpectComplexArgNode extends ExpectArgNode {
        private ExpectComplexArgNode(ExpectMessageNode parent,
                                     Object name, MessagePattern.ArgType argType) {
            super(name,
                  argType == MessagePattern.ArgType.CHOICE ? "choice" :
                  argType == MessagePattern.ArgType.PLURAL ? "plural" : "select");
            this.argType = argType;
            this.parent = parent;
        }
        private ExpectComplexArgNode expectOffset(double offset) {
            this.offset = offset;
            explicitOffset = true;
            return this;
        }
        private ExpectMessageNode expectVariant(String selector) {
            ExpectVariantNode variant = new ExpectVariantNode(this, selector);
            variants.add(variant);
            return variant.msg;
        }
        private ExpectMessageNode expectVariant(String selector, double value) {
            ExpectVariantNode variant = new ExpectVariantNode(this, selector, value);
            variants.add(variant);
            return variant.msg;
        }
        private ExpectMessageNode finishComplexArg() {
            return parent;
        }
        @Override
        protected boolean matches(MessageContentsNode c) {
            boolean ok = super.matches(c);
            if (!ok) {
                return ok;
            }
            ArgNode arg = (ArgNode)c;
            ComplexArgStyleNode complexStyle = arg.getComplexStyle();
            ok &= assertNotNull("unexpected null complex style", complexStyle);
            if (!ok) {
                return ok;
            }
            ok &= assertEquals("unexpected complex-style argType",
                               argType, complexStyle.getArgType());
            ok &= assertEquals("unexpected complex-style hasExplicitOffset()",
                               explicitOffset, complexStyle.hasExplicitOffset());
            ok &= assertEquals("unexpected complex-style offset",
                               offset, complexStyle.getOffset());
            List<VariantNode> complexVariants = complexStyle.getVariants();
            ok &= assertEquals("different number of variants",
                               variants.size(), complexVariants.size());
            if (!ok) {
                return ok;
            }
            Iterator<VariantNode> complexIter = complexVariants.iterator();
            for (ExpectVariantNode variant : variants) {
                ok &= variant.matches(complexIter.next());
            }
            return ok;
        }
        private ExpectMessageNode parent;  // for finishComplexArg()
        private boolean explicitOffset;
        private double offset;
        private List<ExpectVariantNode> variants = new ArrayList<ExpectVariantNode>();
    }

    private class ExpectVariantNode {
        private ExpectVariantNode(ExpectComplexArgNode parent, String selector) {
            this(parent, selector, MessagePattern.NO_NUMERIC_VALUE);
        }
        private ExpectVariantNode(ExpectComplexArgNode parent, String selector, double value) {
            this.selector = selector;
            numericValue = value;
            msg = new ExpectMessageNode();
            msg.parent = parent;
        }
        private boolean matches(VariantNode v) {
            boolean ok = assertEquals("different selector strings",
                                      selector, v.getSelector());
            ok &= assertEquals("different selector strings",
                               isSelectorNumeric(), v.isSelectorNumeric());
            ok &= assertEquals("different selector strings",
                               numericValue, v.getSelectorValue());
            return ok & msg.matches(v.getMessage());
        }
        private boolean isSelectorNumeric() {
            return numericValue != MessagePattern.NO_NUMERIC_VALUE;
        }
        private String selector;
        private double numericValue;
        private ExpectMessageNode msg;
    }

    // The actual tests start here. ---------------------------------------- ***
    // Sample message strings are mostly from the MessagePatternUtilDemo.

    public void TestHello() {
        // No syntax.
        MessageNode msg = MessagePatternUtil.buildMessageNode("Hello!");
        ExpectMessageNode expect = new ExpectMessageNode().expectTextThatContains("Hello");
        expect.checkMatches(msg);
    }

    public void TestHelloWithApos() {
        // Literal ASCII apostrophe.
        MessageNode msg = MessagePatternUtil.buildMessageNode("Hel'lo!");
        ExpectMessageNode expect = new ExpectMessageNode().expectTextThatContains("Hel'lo");
        expect.checkMatches(msg);
    }

    public void TestHelloWithQuote() {
        // Apostrophe starts quoted literal text.
        MessageNode msg = MessagePatternUtil.buildMessageNode("Hel'{o!");
        ExpectMessageNode expect = new ExpectMessageNode().expectTextThatContains("Hel{o");
        expect.checkMatches(msg);
        // Terminating the quote should yield the same result.
        msg = MessagePatternUtil.buildMessageNode("Hel'{'o!");
        expect.checkMatches(msg);
        // Double apostrophe inside quoted literal text still encodes a single apostrophe.
        msg = MessagePatternUtil.buildMessageNode("a'{bc''de'f");
        expect = new ExpectMessageNode().expectTextThatContains("a{bc'def");
        expect.checkMatches(msg);
    }

    public void TestNoneArg() {
        // Numbered argument.
        MessageNode msg = MessagePatternUtil.buildMessageNode("abc{0}def");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("abc").expectNoneArg(0).expectTextThatContains("def");
        expect.checkMatches(msg);
        // Named argument.
        msg = MessagePatternUtil.buildMessageNode("abc{ arg }def");
        expect = new ExpectMessageNode().
            expectTextThatContains("abc").expectNoneArg("arg").expectTextThatContains("def");
        expect.checkMatches(msg);
        // Numbered and named arguments.
        msg = MessagePatternUtil.buildMessageNode("abc{1}def{arg}ghi");
        expect = new ExpectMessageNode().
            expectTextThatContains("abc").expectNoneArg(1).expectTextThatContains("def").
            expectNoneArg("arg").expectTextThatContains("ghi");
        expect.checkMatches(msg);
    }

    public void TestSimpleArg() {
        MessageNode msg = MessagePatternUtil.buildMessageNode("a'{bc''de'f{0,number,g'hi''jk'l#}");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("a{bc'def").expectSimpleArg(0, "number", "g'hi''jk'l#");
        expect.checkMatches(msg);
    }

    public void TestSelectArg() {
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "abc{2, number}ghi{3, select, xx {xxx} other {ooo}} xyz");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("abc").expectSimpleArg(2, "number").
            expectTextThatContains("ghi").
            expectSelectArg(3).
                expectVariant("xx").expectTextThatContains("xxx").finishVariant().
                expectVariant("other").expectTextThatContains("ooo").finishVariant().
                finishComplexArg().
            expectTextThatContains(" xyz");
        expect.checkMatches(msg);
    }

    public void TestPluralArg() {
        // Plural with only keywords.
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "abc{num_people, plural, offset:17 few{fff} other {oooo}}xyz");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("abc").
            expectPluralArg("num_people").
                expectOffset(17).
                expectVariant("few").expectTextThatContains("fff").finishVariant().
                expectVariant("other").expectTextThatContains("oooo").finishVariant().
                finishComplexArg().
            expectTextThatContains("xyz");
        expect.checkMatches(msg);
        // Plural with explicit-value selectors.
        msg = MessagePatternUtil.buildMessageNode(
                "abc{ num , plural , offset: 2 =1 {1} =-1 {-1} =3.14 {3.14} other {oo} }xyz");
        expect = new ExpectMessageNode().
            expectTextThatContains("abc").
            expectPluralArg("num").
                expectOffset(2).
                expectVariant("=1", 1).expectTextThatContains("1").finishVariant().
                expectVariant("=-1", -1).expectTextThatContains("-1").finishVariant().
                expectVariant("=3.14", 3.14).expectTextThatContains("3.14").finishVariant().
                expectVariant("other").expectTextThatContains("oo").finishVariant().
                finishComplexArg().
            expectTextThatContains("xyz");
        expect.checkMatches(msg);
        // Plural with number replacement.
        msg = MessagePatternUtil.buildMessageNode(
                "a_{0,plural,other{num=#'#'=#'#'={1,number,##}!}}_z");
        expect = new ExpectMessageNode().
            expectTextThatContains("a_").
            expectPluralArg(0).
                expectVariant("other").
                    expectTextThatContains("num=").expectReplaceNumber().
                    expectTextThatContains("#=").expectReplaceNumber().
                    expectTextThatContains("#=").expectSimpleArg(1, "number", "##").
                    expectTextThatContains("!").finishVariant().
                finishComplexArg().
            expectTextThatContains("_z");
        expect.checkMatches(msg);
        // Plural with explicit offset:0.
        msg = MessagePatternUtil.buildMessageNode(
                "a_{0,plural,offset:0 other{num=#!}}_z");
        expect = new ExpectMessageNode().
            expectTextThatContains("a_").
            expectPluralArg(0).
                expectOffset(0).
                expectVariant("other").
                    expectTextThatContains("num=").expectReplaceNumber().
                    expectTextThatContains("!").finishVariant().
                finishComplexArg().
            expectTextThatContains("_z");
        expect.checkMatches(msg);
    }

    public void TestChoiceArg() {
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "a_{0,choice,-∞ #-inf|  5≤ five | 99 # ninety'|'nine  }_z");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("a_").
            expectChoiceArg(0).
                expectVariant("#", Double.NEGATIVE_INFINITY).
                    expectTextThatContains("-inf").finishVariant().
                expectVariant("≤", 5).expectTextThatContains(" five ").finishVariant().
                expectVariant("#", 99).expectTextThatContains(" ninety|nine  ").finishVariant().
                finishComplexArg().
            expectTextThatContains("_z");
        expect.checkMatches(msg);
    }

    public void TestComplexArgs() {
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "I don't {a,plural,other{w'{'on't #'#'}} and "+
                "{b,select,other{shan't'}'}} '{'''know'''}' and "+
                "{c,choice,0#can't'|'}"+
                "{z,number,#'#'###.00'}'}.");
        ExpectMessageNode expect = new ExpectMessageNode().
            expectTextThatContains("I don't ").
            expectPluralArg("a").
                expectVariant("other").
                    expectTextThatContains("w{on't ").expectReplaceNumber().
                    expectTextThatContains("#").finishVariant().
                finishComplexArg().
            expectTextThatContains(" and ").
            expectSelectArg("b").
                expectVariant("other").expectTextThatContains("shan't}").finishVariant().
                finishComplexArg().
            expectTextThatContains(" {'know'} and ").
            expectChoiceArg("c").
                expectVariant("#", 0).expectTextThatContains("can't|").finishVariant().
                finishComplexArg().
            expectSimpleArg("z", "number", "#'#'###.00'}'").
            expectTextThatContains(".");
        expect.checkMatches(msg);
    }

    /**
     * @return the text string of the VariantNode's message;
     *         assumes that its message consists of only text
     */
    private String variantText(VariantNode v) {
        return ((TextNode)v.getMessage().getContents().get(0)).getText();
    }

    public void TestPluralVariantsByType() {
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "{p,plural,a{A}other{O}=4{iv}b{B}other{U}=2{ii}}");
        ExpectMessageNode expect = new ExpectMessageNode().
        expectPluralArg("p").
            expectVariant("a").expectTextThatContains("A").finishVariant().
            expectVariant("other").expectTextThatContains("O").finishVariant().
            expectVariant("=4", 4).expectTextThatContains("iv").finishVariant().
            expectVariant("b").expectTextThatContains("B").finishVariant().
            expectVariant("other").expectTextThatContains("U").finishVariant().
            expectVariant("=2", 2).expectTextThatContains("ii").finishVariant().
            finishComplexArg();
        if (!expect.matches(msg)) {
            return;
        }
        List<VariantNode> numericVariants = new ArrayList<VariantNode>();
        List<VariantNode> keywordVariants = new ArrayList<VariantNode>();
        VariantNode other =
            ((ArgNode)msg.getContents().get(0)).getComplexStyle().
            getVariantsByType(numericVariants, keywordVariants);
        assertEquals("'other' selector", "other", other.getSelector());
        assertEquals("message string of first 'other'", "O", variantText(other));

        assertEquals("numericVariants.size()", 2, numericVariants.size());
        VariantNode v = numericVariants.get(0);
        assertEquals("numericVariants[0] selector", "=4", v.getSelector());
        assertEquals("numericVariants[0] selector value", 4., v.getSelectorValue());
        assertEquals("numericVariants[0] text", "iv", variantText(v));
        v = numericVariants.get(1);
        assertEquals("numericVariants[1] selector", "=2", v.getSelector());
        assertEquals("numericVariants[1] selector value", 2., v.getSelectorValue());
        assertEquals("numericVariants[1] text", "ii", variantText(v));

        assertEquals("keywordVariants.size()", 2, keywordVariants.size());
        v = keywordVariants.get(0);
        assertEquals("keywordVariants[0] selector", "a", v.getSelector());
        assertFalse("keywordVariants[0].isSelectorNumeric()", v.isSelectorNumeric());
        assertEquals("keywordVariants[0] text", "A", variantText(v));
        v = keywordVariants.get(1);
        assertEquals("keywordVariants[1] selector", "b", v.getSelector());
        assertFalse("keywordVariants[1].isSelectorNumeric()", v.isSelectorNumeric());
        assertEquals("keywordVariants[1] text", "B", variantText(v));
    }

    public void TestSelectVariantsByType() {
        MessageNode msg = MessagePatternUtil.buildMessageNode(
                "{s,select,a{A}other{O}b{B}other{U}}");
        ExpectMessageNode expect = new ExpectMessageNode().
        expectSelectArg("s").
            expectVariant("a").expectTextThatContains("A").finishVariant().
            expectVariant("other").expectTextThatContains("O").finishVariant().
            expectVariant("b").expectTextThatContains("B").finishVariant().
            expectVariant("other").expectTextThatContains("U").finishVariant().
            finishComplexArg();
        if (!expect.matches(msg)) {
            return;
        }
        // Check that we can use numericVariants = null.
        List<VariantNode> keywordVariants = new ArrayList<VariantNode>();
        VariantNode other =
            ((ArgNode)msg.getContents().get(0)).getComplexStyle().
            getVariantsByType(null, keywordVariants);
        assertEquals("'other' selector", "other", other.getSelector());
        assertEquals("message string of first 'other'", "O", variantText(other));

        assertEquals("keywordVariants.size()", 2, keywordVariants.size());
        VariantNode v = keywordVariants.get(0);
        assertEquals("keywordVariants[0] selector", "a", v.getSelector());
        assertFalse("keywordVariants[0].isSelectorNumeric()", v.isSelectorNumeric());
        assertEquals("keywordVariants[0] text", "A", variantText(v));
        v = keywordVariants.get(1);
        assertEquals("keywordVariants[1] selector", "b", v.getSelector());
        assertFalse("keywordVariants[1].isSelectorNumeric()", v.isSelectorNumeric());
        assertEquals("keywordVariants[1] text", "B", variantText(v));
    }
}
