//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   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 de.ugoe.cs.autoquest.plugin.usability2.rules.operator.visitors;

import static org.fest.assertions.api.Assertions.assertThat;

import java.util.Collection;

import org.junit.Test;

import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.IFilter;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.Label;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.filter.EventTypeFilter;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.transformer.UniqueResultsTransformer;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.visitors.Contains;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.visitors.FindContained;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.AbstractTaskEntryVisitor;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.FollowedByUtil;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.ITaskEntry;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IMatch;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IResult;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
import de.ugoe.cs.autoquest.usability.testutil.GenerateTaskModelUtil;

/**
 * <p>
 * Test of the FollowedBy Operator
 * </p>
 * 
 * @author Konni Hartmann
 */
public class OperatorTest {

    static class TestVisitor extends AbstractTaskEntryVisitor {
        int indentionLevel = 0;

        @Override
        public void visitEntry(ITaskEntry value) {
            StringBuilder indent = new StringBuilder((indentionLevel - 1) * 2);
            for (int i = 1; i < indentionLevel; i++)
                indent.append("  ");
            System.out.printf("%s%s %s %s %s\n", indent, value, value.getReference(),
                              value.getParent(), value.getNext());
        }

        @Override
        public void visit(ITaskEntry value) {
            indentionLevel++;
            super.visit(value);
            indentionLevel--;
        }
    }
    
    @Test
    public void contains_event_positive() {
        // Given
        String spec = 
                "UserSession {" + 
                "  Sequence seq1 {" + 
                "    TextInput t1 { 1 }" +
                "    TextInput t2 { 2 }" + 
                "    Iteration it {" +
                "        Sequence c0 {" +
                "            TextInput t3 { 3 }" +
                "            Sequence c1 {" +
                "                MouseClick {}" +
                "            }" +
                "        }" +
                "    }" + 
                "  }" + 
                "}";

        ITaskModel taskTree = GenerateTaskModelUtil.getTaskModelFromSpec(spec);
        Collection<ITask> tasks = taskTree.getTasks();

        ITask root = tasks.iterator().next();
        //assertThat(tasks.size()).isEqualTo(1);
        // When
        ITaskEntry followTree = FollowedByUtil.generateFollowList(root);
        TestVisitor v = new TestVisitor();
        System.out.println();
        v.visit(followTree);
        
        System.out.println();
                
        IFilter f = new Label("X", new Contains(EventTypeFilter.TEXT_INPUT), UniqueResultsTransformer.UNIQUE_RESULTS_TRANSFORMER);

        IResult result = f.match(root);
        
        System.out.println("\n>>RESULTS:");
        System.out.println(result.isPresent());
        for (IMatch m : result) {
            System.out.println(">"+m.getLabeledResults());
        }
        
        // Then
        assertThat(result.isPresent()).isTrue();
    }
    
    @Test
    public void find_contained_event_positive() {
        // Given
        String spec = 
                "UserSession {" + 
                "  Sequence seq1 {" + 
                "    TextInput t1 { 1 }" +
                "    TextInput t2 { 2 }" + 
                "    Iteration it {" +
                "        Sequence c0 {" +
                "            TextInput t3 { 3 }" +
                "            Sequence c1 {" +
                "                MouseClick {}" +
                "            }" +
                "        }" +
                "    }" + 
                "  }" + 
                "}";

        ITaskModel taskTree = GenerateTaskModelUtil.getTaskModelFromSpec(spec);
        Collection<ITask> tasks = taskTree.getTasks();

        ITask root = tasks.iterator().next();
        //assertThat(tasks.size()).isEqualTo(1);
        // When
        ITaskEntry followTree = FollowedByUtil.generateFollowList(root);
        TestVisitor v = new TestVisitor();
        System.out.println();
        v.visit(followTree);
        
        System.out.println();
        
        IFilter f = new Label("X", new FindContained(EventTypeFilter.TEXT_INPUT));
        
        IResult result = f.match(root);
        
        System.out.println("\n>>RESULTS:");
        System.out.println(result.isPresent());
        for (IMatch m : result) {
            System.out.println(">"+m.getLabeledResults());
        }
        
        // Then
        assertThat(result.isPresent()).isTrue();
    }
}
