/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text;

import com.google.android.collect.Lists;

import android.test.MoreAsserts;
import android.os.Parcel;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.style.StyleSpan;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;

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

import junit.framework.TestCase;

/**
 * TextUtilsTest tests {@link TextUtils}.
 */
public class TextUtilsTest extends TestCase {

    @SmallTest
    public void testBasic() throws Exception {
        assertEquals("", TextUtils.concat());
        assertEquals("foo", TextUtils.concat("foo"));
        assertEquals("foobar", TextUtils.concat("foo", "bar"));
        assertEquals("foobarbaz", TextUtils.concat("foo", "bar", "baz"));

        SpannableString foo = new SpannableString("foo");
        foo.setSpan("foo", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        SpannableString bar = new SpannableString("bar");
        bar.setSpan("bar", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        SpannableString baz = new SpannableString("baz");
        baz.setSpan("baz", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        assertEquals("foo", TextUtils.concat(foo).toString());
        assertEquals("foobar", TextUtils.concat(foo, bar).toString());
        assertEquals("foobarbaz", TextUtils.concat(foo, bar, baz).toString());

        assertEquals(1, ((Spanned) TextUtils.concat(foo)).getSpanStart("foo"));

        assertEquals(1, ((Spanned) TextUtils.concat(foo, bar)).getSpanStart("foo"));
        assertEquals(4, ((Spanned) TextUtils.concat(foo, bar)).getSpanStart("bar"));

        assertEquals(1, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("foo"));
        assertEquals(4, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("bar"));
        assertEquals(7, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("baz"));

        assertTrue(TextUtils.concat("foo", "bar") instanceof String);
        assertTrue(TextUtils.concat(foo, bar) instanceof SpannedString);
    }

    @SmallTest
    public void testTemplateString() throws Exception {
        CharSequence result;

        result = TextUtils.expandTemplate("This is a ^1 of the ^2 broadcast ^3.",
                                          "test", "emergency", "system");
        assertEquals("This is a test of the emergency broadcast system.",
                     result.toString());

        result = TextUtils.expandTemplate("^^^1^^^2^3^a^1^^b^^^c",
                                          "one", "two", "three");
        assertEquals("^one^twothree^aone^b^^c",
                     result.toString());

        result = TextUtils.expandTemplate("^");
        assertEquals("^", result.toString());

        result = TextUtils.expandTemplate("^^");
        assertEquals("^", result.toString());

        result = TextUtils.expandTemplate("^^^");
        assertEquals("^^", result.toString());

        result = TextUtils.expandTemplate("shorter ^1 values ^2.", "a", "");
        assertEquals("shorter a values .", result.toString());

        try {
            TextUtils.expandTemplate("Only ^1 value given, but ^2 used.", "foo");
            fail();
        } catch (IllegalArgumentException e) {
        }

        try {
            TextUtils.expandTemplate("^1 value given, and ^0 used.", "foo");
            fail();
        } catch (IllegalArgumentException e) {
        }

        result = TextUtils.expandTemplate("^1 value given, and ^9 used.",
                                          "one", "two", "three", "four", "five",
                                          "six", "seven", "eight", "nine");
        assertEquals("one value given, and nine used.", result.toString());

        try {
            TextUtils.expandTemplate("^1 value given, and ^10 used.",
                                     "one", "two", "three", "four", "five",
                                     "six", "seven", "eight", "nine", "ten");
            fail();
        } catch (IllegalArgumentException e) {
        }

        // putting carets in the values: expansion is not recursive.

        result = TextUtils.expandTemplate("^2", "foo", "^^");
        assertEquals("^^", result.toString());

        result = TextUtils.expandTemplate("^^2", "foo", "1");
        assertEquals("^2", result.toString());

        result = TextUtils.expandTemplate("^1", "value with ^2 in it", "foo");
        assertEquals("value with ^2 in it", result.toString());
    }

    /** Fail unless text+spans contains a span 'spanName' with the given start and end. */
    private void checkContains(Spanned text, String[] spans, String spanName,
                               int start, int end) throws Exception {
        for (String i: spans) {
            if (i.equals(spanName)) {
                assertEquals(start, text.getSpanStart(i));
                assertEquals(end, text.getSpanEnd(i));
                return;
            }
        }
        fail();
    }

    @SmallTest
    public void testTemplateSpan() throws Exception {
        SpannableString template;
        Spanned result;
        String[] spans;

        // ordinary replacement

        template = new SpannableString("a^1b");
        template.setSpan("before", 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("during", 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("after", 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("during+after", 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        result = (Spanned) TextUtils.expandTemplate(template, "foo");
        assertEquals(5, result.length());
        spans = result.getSpans(0, result.length(), String.class);

        // value is one character longer, so span endpoints should change.
        assertEquals(4, spans.length);
        checkContains(result, spans, "before", 0, 1);
        checkContains(result, spans, "during", 1, 4);
        checkContains(result, spans, "after", 4, 5);
        checkContains(result, spans, "during+after", 1, 5);


        // replacement with empty string

        result = (Spanned) TextUtils.expandTemplate(template, "");
        assertEquals(2, result.length());
        spans = result.getSpans(0, result.length(), String.class);

        // the "during" span should disappear.
        assertEquals(3, spans.length);
        checkContains(result, spans, "before", 0, 1);
        checkContains(result, spans, "after", 1, 2);
        checkContains(result, spans, "during+after", 1, 2);
    }

    @SmallTest
    public void testStringSplitterSimple() {
        stringSplitterTestHelper("a,b,cde", new String[] {"a", "b", "cde"});
    }

    @SmallTest
    public void testStringSplitterEmpty() {
        stringSplitterTestHelper("", new String[] {});
    }

    @SmallTest
    public void testStringSplitterWithLeadingEmptyString() {
        stringSplitterTestHelper(",a,b,cde", new String[] {"", "a", "b", "cde"});
    }

    @SmallTest
    public void testStringSplitterWithInternalEmptyString() {
        stringSplitterTestHelper("a,b,,cde", new String[] {"a", "b", "", "cde"});
    }

    @SmallTest
    public void testStringSplitterWithTrailingEmptyString() {
        // A single trailing emtpy string should be ignored.
        stringSplitterTestHelper("a,b,cde,", new String[] {"a", "b", "cde"});
    }

    private void stringSplitterTestHelper(String string, String[] expectedStrings) {
        TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
        splitter.setString(string);
        List<String> strings = Lists.newArrayList();
        for (String s : splitter) {
            strings.add(s);
        }
        MoreAsserts.assertEquals(expectedStrings, strings.toArray(new String[]{}));
    }

    @SmallTest
    public void testTrim() {
        String[] strings = { "abc", " abc", "  abc", "abc ", "abc  ",
                             " abc ", "  abc  ", "\nabc\n", "\nabc", "abc\n" };

        for (String s : strings) {
            assertEquals(s.trim().length(), TextUtils.getTrimmedLength(s));
        }
    }

    @SmallTest
    public void testRfc822TokenizerFullAddress() {
        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
        assertNotNull(tokens);
        assertEquals(1, tokens.length);
        assertEquals("foo@google.com", tokens[0].getAddress());
        assertEquals("Foo Bar", tokens[0].getName());
        assertEquals("something",tokens[0].getComment());
    }

    @SmallTest
    public void testRfc822TokenizeItemWithError() {
        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("\"Foo Bar\\");
        assertNotNull(tokens);
        assertEquals(1, tokens.length);
        assertEquals("Foo Bar", tokens[0].getAddress());
    }

    @SmallTest
    public void testRfc822FindToken() {
        Rfc822Tokenizer tokenizer = new Rfc822Tokenizer();
        //                0           1         2           3         4
        //                0 1234 56789012345678901234 5678 90123456789012345
        String address = "\"Foo\" <foo@google.com>, \"Bar\" <bar@google.com>";
        assertEquals(0, tokenizer.findTokenStart(address, 21));
        assertEquals(22, tokenizer.findTokenEnd(address, 21));
        assertEquals(24, tokenizer.findTokenStart(address, 25));
        assertEquals(46, tokenizer.findTokenEnd(address, 25));
    }

    @SmallTest
    public void testRfc822FindTokenWithError() {
        assertEquals(9, new Rfc822Tokenizer().findTokenEnd("\"Foo Bar\\", 0));
    }

    @LargeTest
    public void testEllipsize() {
        CharSequence s1 = "The quick brown fox jumps over \u00FEhe lazy dog.";
        CharSequence s2 = new Wrapper(s1);
        Spannable s3 = new SpannableString(s1);
        s3.setSpan(new StyleSpan(0), 5, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        TextPaint p = new TextPaint();
        p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG);

        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 3; j++) {
                TextUtils.TruncateAt kind = null;

                switch (j) {
                case 0:
                    kind = TextUtils.TruncateAt.START;
                    break;

                case 1:
                    kind = TextUtils.TruncateAt.END;
                    break;

                case 2:
                    kind = TextUtils.TruncateAt.MIDDLE;
                    break;
                }

                String out1 = TextUtils.ellipsize(s1, p, i, kind).toString();
                String out2 = TextUtils.ellipsize(s2, p, i, kind).toString();
                String out3 = TextUtils.ellipsize(s3, p, i, kind).toString();

                String keep1 = TextUtils.ellipsize(s1, p, i, kind, true, null).toString();
                String keep2 = TextUtils.ellipsize(s2, p, i, kind, true, null).toString();
                String keep3 = TextUtils.ellipsize(s3, p, i, kind, true, null).toString();

                String trim1 = keep1.replace("\uFEFF", "");

                // Are all normal output strings identical?
                assertEquals("wid " + i + " pass " + j, out1, out2);
                assertEquals("wid " + i + " pass " + j, out2, out3);

                // Are preserved output strings identical?
                assertEquals("wid " + i + " pass " + j, keep1, keep2);
                assertEquals("wid " + i + " pass " + j, keep2, keep3);

                // Does trimming padding from preserved yield normal?
                assertEquals("wid " + i + " pass " + j, out1, trim1);

                // Did preserved output strings preserve length?
                assertEquals("wid " + i + " pass " + j, keep1.length(), s1.length());

                // Does the output string actually fit in the space?
                assertTrue("wid " + i + " pass " + j, p.measureText(out1) <= i);

                // Is the padded output the same width as trimmed output?
                assertTrue("wid " + i + " pass " + j, p.measureText(keep1) == p.measureText(out1));
            }
        }
    }

    @SmallTest
    public void testDelimitedStringContains() {
        assertFalse(TextUtils.delimitedStringContains("", ',', null));
        assertFalse(TextUtils.delimitedStringContains(null, ',', ""));
        // Whole match
        assertTrue(TextUtils.delimitedStringContains("gps", ',', "gps"));
        // At beginning.
        assertTrue(TextUtils.delimitedStringContains("gps,gpsx,network,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("gps,network,mock", ',', "gps"));
        // In middle, both without, before & after a false match.
        assertTrue(TextUtils.delimitedStringContains("network,gps,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,gps,gpsx,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,gpsx,gps,mock", ',', "gps"));
        // At the end.
        assertTrue(TextUtils.delimitedStringContains("network,mock,gps", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,mock,gpsx,gps", ',', "gps"));
        // Not present (but with a false match)
        assertFalse(TextUtils.delimitedStringContains("network,mock,gpsx", ',', "gps"));
    }

    @SmallTest
    public void testCharSequenceCreator() {
        Parcel p = Parcel.obtain();
        TextUtils.writeToParcel(null, p, 0);
        CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
        assertNull("null CharSequence should generate null from parcel", text);
        p = Parcel.obtain();
        TextUtils.writeToParcel("test", p, 0);
        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
        assertEquals("conversion to/from parcel failed", "test", text);
    }

    @SmallTest
    public void testCharSequenceCreatorNull() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        TextUtils.writeToParcel(null, p, 0);
        p.setDataPosition(0);
        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
        assertNull("null CharSequence should generate null from parcel", text);
    }

    @SmallTest
    public void testCharSequenceCreatorSpannable() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        TextUtils.writeToParcel(new SpannableString("test"), p, 0);
        p.setDataPosition(0);
        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
        assertEquals("conversion to/from parcel failed", "test", text.toString());
    }

    @SmallTest
    public void testCharSequenceCreatorString() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        TextUtils.writeToParcel("test", p, 0);
        p.setDataPosition(0);
        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
        assertEquals("conversion to/from parcel failed", "test", text.toString());
    }

    /**
     * CharSequence wrapper for testing the cases where text is copied into
     * a char array instead of working from a String or a Spanned.
     */
    private static class Wrapper implements CharSequence {
        private CharSequence mString;

        public Wrapper(CharSequence s) {
            mString = s;
        }

        public int length() {
            return mString.length();
        }

        public char charAt(int off) {
            return mString.charAt(off);
        }

        @Override
        public String toString() {
            return mString.toString();
        }

        public CharSequence subSequence(int start, int end) {
            return new Wrapper(mString.subSequence(start, end));
        }
    }

    @LargeTest
    public void testRemoveEmptySpans() {
        MockSpanned spanned = new MockSpanned();

        spanned.test();
        spanned.addSpan().test();
        spanned.addSpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();

        spanned.clear();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();

        spanned.clear();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addSpan().test();
    }

    protected static class MockSpanned implements Spanned {

        private List<Object> allSpans = new ArrayList<Object>();
        private List<Object> nonEmptySpans = new ArrayList<Object>();

        public void clear() {
            allSpans.clear();
            nonEmptySpans.clear();
        }

        public MockSpanned addSpan() {
            Object o = new Object();
            allSpans.add(o);
            nonEmptySpans.add(o);
            return this;
        }

        public MockSpanned addEmptySpan() {
            Object o = new Object();
            allSpans.add(o);
            return this;
        }

        public void test() {
            Object[] nonEmpty = TextUtils.removeEmptySpans(allSpans.toArray(), this, Object.class);
            assertEquals("Mismatched array size", nonEmptySpans.size(), nonEmpty.length);
            for (int i=0; i<nonEmpty.length; i++) {
                assertEquals("Span differ", nonEmptySpans.get(i), nonEmpty[i]);
            }
        }

        public char charAt(int arg0) {
            return 0;
        }

        public int length() {
            return 0;
        }

        public CharSequence subSequence(int arg0, int arg1) {
            return null;
        }

        @Override
        public <T> T[] getSpans(int start, int end, Class<T> type) {
            return null;
        }

        @Override
        public int getSpanStart(Object tag) {
            return 0;
        }

        @Override
        public int getSpanEnd(Object tag) {
            return nonEmptySpans.contains(tag) ? 1 : 0;
        }

        @Override
        public int getSpanFlags(Object tag) {
            return 0;
        }

        @Override
        public int nextSpanTransition(int start, int limit, Class type) {
            return 0;
        }
    }
}
