/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.sling.ide.test.impl.ui.sightly;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assume.assumeThat;

import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.sling.ide.test.impl.helpers.ProjectAdapter;
import org.apache.sling.ide.test.impl.helpers.TemporaryProject;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEclipseEditor;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(SWTBotJunit4ClassRunner.class)
public class SightlyAutocompletionTest {
    
    private static SWTWorkbenchBot bot;
    
    @Rule
    public TemporaryProject projectRule = new TemporaryProject();
    
    @BeforeClass
    public static void closeWelcomeView() throws Exception {
        bot = new SWTWorkbenchBot();
        if ( bot.activeView().getTitle().equals("Welcome") ) {
            bot.activeView().close();
        }
    }    

    @Test
    public void tagNameAutocompletion() throws Exception {
        
        assumeThat(System.getProperty("os.name"), not(containsString("Windows"))); // TODO - SLING-7596

        List<String> proposals = new AutocompletionCallable() {
            @Override
            protected void prepareEditor(SWTBotEclipseEditor editor) {
                editor.insertText("<html>\n\n</html>");
                editor.navigateTo(1, 0);
            }
        }.call();
        

        // validate auto-completion proposals
        assertThat("proposal list does not contain 'sly'", proposals, hasItem("sly"));
    }
    
    @Test
    public void attributeAutocompletion() throws Exception {

        assumeThat(System.getProperty("os.name"), not(containsString("Windows"))); // TODO - SLING-7596

        List<String> proposals = new AutocompletionCallable() {
            @Override
            protected void prepareEditor(SWTBotEclipseEditor editor) {
                editor.insertText("<html>\n<div  ></div>\n</html>");
                editor.navigateTo(1, 5);
            }
        }.call();

        // validate auto-completion proposals
        assertThat("proposal list does not contain 'data-sly-test'", proposals, hasItem("data-sly-test"));
    }
    
    abstract class AutocompletionCallable implements Callable<List<String>> {
        
        @Override
        public List<String> call() throws Exception {
            
            // create faceted project
            final IProject contentProject = projectRule.getProject();

            ProjectAdapter project = new ProjectAdapter(contentProject);
            project.addNatures(JavaCore.NATURE_ID, "org.eclipse.wst.common.project.facet.core.nature");

            // install facets
            project.installFacet("sling.content", "1.0");
            project.installFacet("sightly", "1.1");
            
            // create basic html file
            project.createOrUpdateFile(Path.fromOSString("jcr_root/index.html"), new ByteArrayInputStream("".getBytes()));

            // ensure that we get the tree from the project explorer
            SWTBotView projectExplorer = bot.viewByTitle("Project Explorer");
            projectExplorer.setFocus();
            
            final SWTBotTree explorerTree = projectExplorer.bot().tree();

            // wait until the project is displayed in the project explorer
            bot.waitUntil(new DefaultCondition() {
                @Override
                public boolean test() throws Exception {
                    SWTBotTreeItem[] treeItems = explorerTree.getAllItems();

                    for (SWTBotTreeItem treeItem : treeItems) {
                        if ( contentProject.getName().equals(treeItem.getText()) ) {
                            return true;
                        }
                    }

                    return false;
                }
                @Override
                public String getFailureMessage() {
                    return "No project named '" + contentProject.getName() + "' found in the Project Explorer.";
                }
            });

            // open editor
            SWTBotTreeItem projectItem = explorerTree.expandNode(contentProject.getName());
            // it seems that two 'jcr_root' nodes confuse SWTBot so we expand and navigate manually
            SWTBotTreeItem folderNode = projectItem.getItems()[0].expand();
            folderNode.getItems()[0].select().doubleClick();
            
            // generate auto-completion proposals
            SWTBotEclipseEditor editor = bot.editorByTitle("index.html").toTextEditor();
            prepareEditor(editor);

            // gather proposals
            List<String> proposals = editor.getAutoCompleteProposals("");
            
            // close editor, otherwise cleanup can hang due to the dialog
            editor.saveAndClose();

            return proposals;
        }

        /**
         * Prepare the editor by adding text and positioning the cursor
         * 
         * <p>After this method is executed the editor must be ready to generate
         * the autocompletions expected by the test</p>
         * 
         * @param editor the editor instance, never <code>null</code>
         */
        protected abstract void prepareEditor(SWTBotEclipseEditor editor);
        
    }

}
