
import SequenceEvaluator from "../domain/SequenceEvaluator";
import SequenceEvaluatorRepository from "../domain/SequenceEvaluatorRepository";
import Step from "../domain/Step";
import StepFactory from "../domain/StepFactory";
import AntlrStepParser from "./AntlrStepParser";
import {sequenceEvaluatorModel} from "./SequenceEvaluatorSchema";

export default class SequenceEvaluatorRepositoryMongo implements SequenceEvaluatorRepository {

    private stepFactory: StepFactory;

    constructor() {
        this.stepFactory = new StepFactory(new AntlrStepParser());
    }

    public getSequenceEvaluatorByWebSiteId(webSiteId: string): Promise<SequenceEvaluator | null> {
        return sequenceEvaluatorModel.findOne({webSiteId})
        .then((sequenceEvaluatorData) => {
            if (sequenceEvaluatorData) {
                const evaluator = new SequenceEvaluator(sequenceEvaluatorData._id);
                return Promise.all(sequenceEvaluatorData.stepList.map((stepData) => this.stepFactory.createStep(stepData.name, stepData.expression)))
                    .then((values) => {
                        const steplist = values as Step[];
                        evaluator.stepList = steplist;
                        return evaluator;
                    });
            }
        })
        .then((evaluator) => {
            if (!evaluator) {
                return null;
            }
            return evaluator;
        });
    }

    public createSequenceEvaluator(webSiteId: string, stepList: Array<{name: string, expression: string}>): Promise<SequenceEvaluator> {
        let evaluator;
        return sequenceEvaluatorModel.create({
            webSiteId,
            stepList,
        }).then((createdSequenceEvaluator) => {
            evaluator = new SequenceEvaluator(createdSequenceEvaluator._id);
            return Promise.all(createdSequenceEvaluator.stepList.map((stepData) => this.stepFactory.createStep(stepData.name, stepData.expression)));
        }).then(() => {
            return evaluator;
        }).catch((error) => {
            console.log(error);
        });
    }

    public updateSequenceEvaluator(webSiteId: string, stepList: Array<{name: string, expression: string}>): Promise <void> {
        return sequenceEvaluatorModel.update({
            webSiteId,
        }, {
            stepList,
        })
    }

    public removeSequenceEvaluator(sequenceEvaluator: SequenceEvaluator): Promise<void> {
        return sequenceEvaluatorModel.removeOne({_id: sequenceEvaluator.id});
    }

}
