import chai = require("chai");
const expect = chai.expect;
import "mocha";
import AntlrStepParser from "../../src/_infra/AntlrStepParser";
import Action from "../../src/domain/Action";
import InteractionFactory from "../../src/domain/InteractionFactory";
import Question from "../../src/domain/Question";
import SequenceEvaluator from "../../src/domain/SequenceEvaluator";
import StepFactory from "../../src/domain/StepFactory";
import SequenceEvaluation from "../../src/domain/SequenceEvaluation";
import * as fs from "fs";
import * as path from "path";
import Step from "../../src/domain/Step";

const stepParser = new AntlrStepParser();
const stepFactory = new StepFactory(stepParser);
describe("Domain - SequenceEvaluator", () => {
    describe.only("Simple Action", () => {

        describe("Action", () => {

            const text = "action1"
            let evaluator: SequenceEvaluator;
            let webSiteId = "1";
            let step; 

            it ("initialize evaluator", () => {
                evaluator = new SequenceEvaluator(webSiteId);
                return stepFactory.createStep("myStep", text, [])
                    .then((createdStep: Step) => {
                        step = createdStep;

                        evaluator.addStep(step);
                    })
            })

            it ("Valide sequence", () => {
                const interactionList = [
                    InteractionFactory.parseInteraction("action1"),
                ];
                
                return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                    expect(evaluationResult.validatedStepList.length).eql(1)
                    expect(evaluationResult.validatedStepList[0]).eql(step)
                })
            })

        })

        describe("Action with suffix", () => {
            const text = "action1$mySuffix"
            let evaluator: SequenceEvaluator;
            let webSiteId = "1";
            let step; 

            it ("initialize evaluator", () => {
                evaluator = new SequenceEvaluator(webSiteId);
                return stepFactory.createStep("myStep", text, [])
                    .then((createdStep: Step) => {
                        step = createdStep;

                        evaluator.addStep(step);
                    })
            })

            it ("Valide sequence", () => {
                const interactionList = [
                    InteractionFactory.parseInteraction("action1$mySuffix"),
                ];
                
                return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                    expect(evaluationResult.validatedStepList.length).eql(1)
                    expect(evaluationResult.validatedStepList[0]).eql(step)
                })
            })

        })

        describe("Action with simple quote suffix", () => {
            const text = "action1$'my Suffix'"
            let evaluator: SequenceEvaluator;
            let webSiteId = "1";
            let step; 

            it ("initialize evaluator", () => {
                evaluator = new SequenceEvaluator(webSiteId);
                return stepFactory.createStep("myStep", text, [])
                    .then((createdStep: Step) => {
                        step = createdStep;

                        evaluator.addStep(step);
                    })
            })

            it ("Valide sequence", () => {
                const interactionList = [
                    InteractionFactory.parseInteraction("action1$my Suffix"),
                ];
                
                return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                    expect(evaluationResult.validatedStepList.length).eql(1)
                    expect(evaluationResult.validatedStepList[0]).eql(step)
                })
            })

        })
    })

    describe("Action with double quote suffix", () => {
        const text = "action1$\"my Suffix\""
        let evaluator: SequenceEvaluator;
        let webSiteId = "1";
        let step; 

        it ("initialize evaluator", () => {
            evaluator = new SequenceEvaluator(webSiteId);
            return stepFactory.createStep("myStep", text, [])
                .then((createdStep: Step) => {
                    step = createdStep;

                    evaluator.addStep(step);
                })
        })

        it ("Valide sequence", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("action1$my Suffix"),
            ];
            
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(1)
                expect(evaluationResult.validatedStepList[0]).eql(step)
            })
        })

    })

    describe("KleenPlus", () => {
        const text = "(clickButton1 or clickButton2)+ clickButton3"
        let evaluator: SequenceEvaluator;
        let webSiteId = "1";
        let step; 

        it ("initialize evaluator", () => {
            evaluator = new SequenceEvaluator(webSiteId);
            return stepFactory.createStep("myStep", text, [])
                .then((createdStep: Step) => {
                    step = createdStep;

                    evaluator.addStep(step);
                })
        })

        it ("Valide sequence", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(1)
                expect(evaluationResult.validatedStepList[0]).eql(step)
            })
        })

        it ("Invalid sequence 1", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })

        it ("Invalid sequence 2", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton1"),
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })

        it ("Invalid sequence 2", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton3"),
                InteractionFactory.parseInteraction("clickButton3")
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })
    })

    describe("Iteration", () => {

        const text = "(clickButton1 or clickButton2)[2] clickButton3"
        let evaluator: SequenceEvaluator;
        let webSiteId = "1";
        let step; 

        it ("initialize evaluator", () => {
            evaluator = new SequenceEvaluator(webSiteId);
            return stepFactory.createStep("myStep", text, [])
                .then((createdStep: Step) => {
                    step = createdStep;

                    evaluator.addStep(step);
                })
        })

        it ("Valide sequence", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(1)
                expect(evaluationResult.validatedStepList[0]).eql(step)
            })
        })
        it ("Valide sequence 2", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton2"),
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(1)
                expect(evaluationResult.validatedStepList[0]).eql(step)
            })
        })
        it ("Invalid sequence 1", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton1"),
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })

        it ("Invalid sequence 2", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton2"),
                InteractionFactory.parseInteraction("clickButton3"),
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })

        it ("Invalid sequence 3", () => {
            const interactionList = [
                InteractionFactory.parseInteraction("clickButton2"),
                InteractionFactory.parseInteraction("clickButton2"),
                InteractionFactory.parseInteraction("clickButton2"),
                InteractionFactory.parseInteraction("clickButton3")
            ];
            return evaluator.evaluate(interactionList).then((evaluationResult:SequenceEvaluation) => {
                expect(evaluationResult.validatedStepList.length).eql(0)
            })
        })
    })

   
})