/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.editors;

import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

@SuppressWarnings("javadoc")
public class AndroidXmlAutoEditStrategyTest extends AdtProjectTest {

    public void checkInsertNewline(String before, String after) throws Exception {
        AndroidXmlAutoEditStrategy s = new AndroidXmlAutoEditStrategy();

        // All tests just operate on the "edithandling" document; the contents are
        // ignored and replaced with the before-document passed in
        IFile file = getLayoutFile(getProject(), "edithandling.xml");

        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        assertNotNull(page);
        IEditorPart editor = IDE.openEditor(page, file);
        assertTrue(editor instanceof AndroidXmlEditor);
        AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor;
        ISourceViewer viewer = layoutEditor.getStructuredSourceViewer();

        String newDocumentContent = stripCaret(before);
        IDocument document = viewer.getDocument();
        document.replace(0, document.getLength(), newDocumentContent);

        // Determine the offset, and possibly make text range selections as well
        int offset = updateCaret(viewer, before);

        DocumentCommand c = new TestDocumentCommand();
        c.doit = true;
        c.offset = offset;
        c.caretOffset = -1;
        c.length = 0;
        c.text = "\n";

        s.customizeDocumentCommand(document, c);

        if (c.doit) {
            if (c.length == 0 && c.text == null) {
                return;
            }

            document.replace(c.offset, c.length, c.text);

            int caretOffset = c.offset + c.text.length();

            // The shiftsCaret flag doesn't behave the way it's documented to
            //if (c.shiftsCaret && c.caretOffset != -1) {
            if (c.caretOffset != -1) {
                caretOffset = c.caretOffset;
            }
            viewer.setSelectedRange(caretOffset, 0);
        }

        String text = document.get();
        Point selectedRange = viewer.getSelectedRange();
        assert selectedRange.y == 0;
        String textWithCaret = text;
        if (selectedRange.x >= 0) {
            textWithCaret = text.substring(0, selectedRange.x) + "^" +
                text.substring(selectedRange.x);
        }

        assertEquals(after, textWithCaret);
    }

    private static String stripCaret(String s) {
        int index = s.indexOf('^');
        assertTrue(index != -1);
        return s.substring(0, index) + s.substring(index + 1);
    }

    public void testCornerCase1() throws Exception {
        checkInsertNewline("^", "\n^");
    }

    public void testCornerCase2() throws Exception {
        checkInsertNewline(
                "\n^",

                "\n\n^");
    }

    public void testCornerCase3() throws Exception {
        checkInsertNewline(
                "    ^",

                "    \n" +
                "    ^");
    }

    public void testSimpleIndentation1() throws Exception {
        checkInsertNewline(
                "   ^ ",

                "   \n" +
                "   ^ ");
    }

    public void testSimpleIndentation2() throws Exception {
        checkInsertNewline(
                "\n" +
                "   foo^\n",

                "\n" +
                "   foo\n" +
                "   ^\n");
    }

    public void testSimpleIndentation3() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <newtag>^\n",

                "\n" +
                "    <newtag>\n" +
                "        ^\n");
    }

    public void testSimpleIndentation4() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <newtag/>^\n",

                "\n" +
                "    <newtag/>\n" +
                "    ^\n");
    }

    public void testSimpleIndentation5() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <newtag^\n",
                "\n" +
                "    <newtag\n" +
                "        ^\n");
    }

    public void testSplitAttribute() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <newtag ^attribute='value'/>\n",

                "\n" +
                "    <newtag \n" +
                "        ^attribute='value'/>\n");
    }

    public void testIndentationInComments1() throws Exception {
        // Make sure that inside a comment we ignore tags etc
        checkInsertNewline(
                "<!--\n   foo^\n--->\n",

                "<!--\n   foo\n   ^\n--->\n");
    }

    public void testIndentationInComments2() throws Exception {
        // Make sure that inside a comment we ignore tags etc
        checkInsertNewline(
                "\n" +
                "<!--\n" +
                "<foo><^\n" +
                "-->\n",

                "\n" +
                "<!--\n" +
                "<foo><\n" +
                "^\n" +
                "-->\n");
    }

    public void testSurroundCaret() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <item>^</item>\n",

                "\n" +
                "    <item>\n" +
                "        ^\n" +
                "    </item>\n");
    }

    public void testSurroundCaret2() throws Exception {
        // This test combines both surround with and continuing earlier lines (where
        // it searches for a matching tag)
        checkInsertNewline(
                "\n" +
                "    <foo\n" +
                "        name='value'>^</foo>\n",

                "\n" +
                "    <foo\n" +
                "        name='value'>\n" +
                "        ^\n" +
                "    </foo>\n");
    }

    public void testContinueEarlierLine1() throws Exception {
        // Here we need to indent to the exact location of an earlier line
        checkInsertNewline(
                "\n" +
                "    <foo\n" +
                "        name='value'/>^\n",

                "\n" +
                "    <foo\n" +
                "        name='value'/>\n" +
                "    ^\n");
    }

    public void testContinueEarlierLine2() throws Exception {
        checkInsertNewline(
                "\n" +
                "    <foo\n" +
                "        name='value'></foo>^\n",

                "\n" +
                "    <foo\n" +
                "        name='value'></foo>\n" +
                "    ^\n");
        // Note that
        //    <foo
        //           >
        //    </foo>
        // does not require special handling, this only happens with the closing tag is sharing
        // a line.
    }

    public void testContinueEarlierLine3() throws Exception {
        // Make sure the code to look up the corresponding opening tag works properly
        checkInsertNewline(
                "\n" +
                "    <foo\n" +
                "        name='value'><bar></bar><baz/></foo>^\n",

                "\n" +
                "    <foo\n" +
                "        name='value'><bar></bar><baz/></foo>\n" +
                "    ^\n");
    }

    public void testContinueEarlierLine4() throws Exception {
        checkInsertNewline(
                "    <Button\n" +
                "        android:id=\"@+id/button1\"\n" +
                "        android:layout_width=\"wrap_content\"\n" +
                "        android:layout_height=\"wrap_content\"\n" +
                "        android:text=\"Button\" >^\n" +
                "    </Button>\n",

                "    <Button\n" +
                "        android:id=\"@+id/button1\"\n" +
                "        android:layout_width=\"wrap_content\"\n" +
                "        android:layout_height=\"wrap_content\"\n" +
                "        android:text=\"Button\" >\n" +
                "        ^\n" +
                "    </Button>\n");
    }

    public void testIndent() throws Exception {
        checkInsertNewline(
                "    <Button\n" +
                "        attr=\"value\"></Button>^\n",

                "    <Button\n" +
                "        attr=\"value\"></Button>\n" +
                "    ^\n" +
                "");
    }

    public void testLineBeginning1() throws Exception {
        // Test that if you insert on a blank line, we just add a newline and indent
        checkInsertNewline(
                "<foo>\n" +
                "^\n" +
                "</foo>",

                "<foo>\n" +
                "\n" +
                "    ^\n" +
                "</foo>");
    }

    public void testLineBeginning2() throws Exception {
        // Test that if you insert with the caret on the beginning of a line that has
        // content, we insert an indent correctly
        checkInsertNewline(
                "<foo>\n" +
                "^    <bar/>\n" +
                "</foo>",

                "<foo>\n" +
                "\n" +
                "    ^<bar/>\n" +
                "</foo>");
    }

    public void testLineBeginning3() throws Exception {
        checkInsertNewline(
                "<foo>\n" +
                "    <bar>\n" +
                "^\n" +
                "        <baz/>\n" +
                "    </bar>\n" +
                "</foo>",

                "<foo>\n" +
                "    <bar>\n" +
                "\n" +
                "        ^\n" +
                "        <baz/>\n" +
                "    </bar>\n" +
                "</foo>");

    }

    public void testLineBeginning4() throws Exception {
        // Test that if you insert with the caret on the beginning of a line that has
        // content, we insert an indent correctly
        checkInsertNewline(
                "<foo>\n" +
                "    <bar>\n" +
                "\n" +
                "^        <baz/>\n" +
                "    </bar>\n" +
                "</foo>",

                "<foo>\n" +
                "    <bar>\n" +
                "\n" +
                "\n" +
                "        ^<baz/>\n" +
                "    </bar>\n" +
                "</foo>");
    }

    public void testLineBeginning5() throws Exception {
        // Test that if you insert with the caret on the beginning of a line that has
        // content, we insert an indent correctly
        checkInsertNewline(
                "<foo>\n" +
                "    <bar>\n" +
                "\n" +
                "    ^    <baz/>\n" +
                "    </bar>\n" +
                "</foo>",

                "<foo>\n" +
                "    <bar>\n" +
                "\n" +
                "    \n" +
                "        ^<baz/>\n" +
                "    </bar>\n" +
                "</foo>");
    }

    public void testLineBeginning6() throws Exception {

        checkInsertNewline(
                "    <foo>\n" +
                "        <bar>\n" +
                "            \n" +
                "        \n" +
                "^        </bar>\n" +
                "    </foo>\n",

                "    <foo>\n" +
                "        <bar>\n" +
                "            \n" +
                "        \n" +
                "\n" +
                "        ^</bar>\n" +
                "    </foo>\n");
    }

    public void testBlankContinuation() throws Exception {

        checkInsertNewline(
                "    <foo>\n" +
                "        <bar>\n" +
                "            ^\n" +
                "        </bar>\n" +
                "    </foo>\n" +
                "",

                "    <foo>\n" +
                "        <bar>\n" +
                "            \n" +
                "            ^\n" +
                "        </bar>\n" +
                "    </foo>\n" +
                "");
    }

    public void testIssue22332a() throws Exception {
        checkInsertNewline(
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<resources>\n" +
                "\n" +
                "    <string name=\"hello\">Hello World, MainActivity!</string>^\n" +
                "\n" +
                "</resources>",

                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<resources>\n" +
                "\n" +
                "    <string name=\"hello\">Hello World, MainActivity!</string>\n" +
                "    ^\n" +
                "\n" +
                "</resources>");
    }

    public void testIssue22332b() throws Exception {
        checkInsertNewline(
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                        "<resources>\n" +
                        "\n" +
                        "    <string name=\"hello\">Hello World, MainActivity!</string>\n" +
                        "    ^\n" +
                        "\n" +
                        "</resources>",

                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                        "<resources>\n" +
                        "\n" +
                        "    <string name=\"hello\">Hello World, MainActivity!</string>\n" +
                        "    \n" +
                        "    ^\n" +
                        "\n" +
                        "</resources>");
    }

    /**
     * To test
     *    When you press / after < I should reindent the current line. For example,
     *    if you have
     *        <foo>
     *            <bar>
     *            </ the moment you've typed this we should dedent it back out
     *    When you press newline we need to reindent
     */

    /** Subclassed for test usage since constructor is protected */
    private class TestDocumentCommand extends DocumentCommand {
        public TestDocumentCommand() {
        }
    }
}
