package org.drools.model.consequences;

import org.drools.model.Consequence;
import org.drools.model.Drools;
import org.drools.model.RuleItemBuilder;
import org.drools.model.Variable;
import org.drools.model.functions.*;
import org.drools.model.functions.ScriptBlock;

// Generated by ConsequenceGenerator, please do not change this file manually
public class ConsequenceBuilder {

    public _0 execute(Block0 block) {
        return new _0(block);
    }

    public _0 execute(Block1<Drools> block) {
        return new _0(block);
    }

    public <A> _1<A> on(Variable<A> dec1) {
        return new _1(dec1);
    }

    public <A, B> _2<A, B> on(Variable<A> decl1, Variable<B> decl2) {
        return new _2(decl1, decl2);
    }

    public interface ValidBuilder extends RuleItemBuilder<Consequence> { }

    public static abstract class AbstractValidBuilder<T extends AbstractValidBuilder> implements ValidBuilder {
        private final Variable[] declarations;
        protected BlockN block;
        protected boolean usingDrools = false;
        protected boolean breaking = false;
        protected String language = "java";

        protected AbstractValidBuilder(Variable... declarations) {
            this.declarations = declarations;
        }

        @Override
        public Consequence get() {
            return new ConsequenceImpl( block,
                                        declarations,
                                        usingDrools,
                                        breaking,
                                        language);
        }

        public T breaking() {
            breaking = true;
            return (T) this;
        }
    }

    public static class _0 extends AbstractValidBuilder<_0> {
        public _0(final Block0 block) {
            super(new Variable[0]);
            this.block = block.asBlockN();
        }

        public _0(final Block1<Drools> block) {
            super();
            this.usingDrools = true;
            this.block = block.asBlockN();
        }

        public _0(String language, Class<?> ruleClass, String script) {
            super();
            this.usingDrools = true;
            this.language = language;
            this.block = new ScriptBlock(ruleClass, script);
        }
    }

    // This is used as both an example and the template with which the inner class is generated
    public static class _ARITY_CLASS_NAME<A, B, C, D, E> extends AbstractValidBuilder<_ARITY_CLASS_NAME<A,B,C,D,E>> {
        public _ARITY_CLASS_NAME(Variable<A> decl1, Variable<B> decl2, Variable<C> decl3, Variable<D> decl4, Variable<E> decl5) {
            super(decl1, decl2, decl3, decl4, decl5);
        }

        public _ARITY_CLASS_NAME<A, B, C, D, E> execute(final _ARITY_BLOCK<A, B, C, D, E> block) {
            this.block = block.asBlockN();
            return this;
        }

        public _ARITY_CLASS_NAME<A, B, C, D, E> execute(final _ARITY_BLOCK_PLUS_ONE<Drools, A, B, C, D, E> block ) {
            this.usingDrools = true;
            this.block = block.asBlockN();
            return this;
        }

        public _ARITY_CLASS_NAME<A, B, C, D, E> executeScript(String language, Class<?> ruleClass, String script) {
            this.usingDrools = true;
            this.language = language;
            this.block = new ScriptBlock(ruleClass, script);
            return this;
        }
    }

    public static class _N extends AbstractValidBuilder<_N> {

        public _N(Variable... declarations) {
            super(declarations);
        }

        public _N executeScript(String language, Class<?> ruleClass, String script) {
            this.usingDrools = true;
            this.language = language;
            this.block = new ScriptBlock(ruleClass, script);
            return this;
        }
    }
}
