import Action from "./actions/action";
import ActionPipeline from "./actions/actionPipeline";
import ClickAction from "./actions/clickAction";
import ComplexAction from "./actions/complexAction";
import GoToAction from "./actions/gotoAction";
import KeyupAction from "./actions/keyup";
import MouseOverAction from "./actions/mouseOverAction";
import TypeAction from "./actions/typeAction";
import { Rule } from "./rule";
import Word from "./word";

export default class Replayer {

    public rules: Rule[];
    public baseURL: string;

    constructor(rules: Rule[], baseURL: string) {
        this.rules = rules;
        this.baseURL = baseURL;
    }

    public executeTrace(words: Word[]): Promise<Word[]> {
        const pipeline = new ActionPipeline();
        for (const word of words) {
            const actions = this.createActions(word);
            if (actions && actions.length > 0) {
                for (const action of actions) {
                    pipeline.addAction(action);
                }
            }
        }
        return pipeline.execute().then((executedActions) => {
            return executedActions.map((action) => action.toWord());
        });
    }

    public createActions(word: Word): Action[] {
        const rule = this.rules.find((ruleElem) => ruleElem.isMatched(word));
        const actions = [];
        if (rule === undefined) {
            throw new Error("No rule found for word : " + word);
        } else {
            if (rule.prefix === "start") {
                actions.push(new GoToAction(word, null, this.baseURL));
                return actions;
            }
            if (rule.prefix === "end") {
                return actions;
            }
            if (rule.event === "keyup" && rule.suffix === "value") {
                actions.push(new ComplexAction(word, rule, [new TypeAction(word, null, rule.selector, word.suffix), new KeyupAction(word, rule, rule.code)]));
                return actions;
            }
            switch (rule.event) {
                case "click":
                    actions.push(new ClickAction(word, rule, rule.selector));
                    break;
                case "mouseover":
                    actions.push(new MouseOverAction(word, rule, rule.selector));
                    break;
                case "change":
                    actions.push(new TypeAction(word, rule, rule.selector, word.suffix));
                    break;
                case "keyup":
                    actions.push();
                    break;
                default:
                    console.error("No action defined for ", rule.event);
            }
            return actions;
        }
    }

}
