/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.wayang.core.platform;

import org.apache.wayang.core.optimizer.OptimizationContext;
import org.apache.wayang.core.plan.executionplan.ExecutionStage;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * {@link Breakpoint} implementation that disrupts execution if all aggregated {@link Breakpoint}s request a disruption.
 * However, if no {@link Breakpoint} conjuncts are set up, then it will never break.
 */
public class ConjunctiveBreakpoint implements Breakpoint {

    private final List<Breakpoint> conjuncts;

    public ConjunctiveBreakpoint(Breakpoint... conjuncts) {
        this.conjuncts = new LinkedList<>(Arrays.asList(conjuncts));
        assert this.conjuncts.stream().allMatch(Objects::nonNull);
    }

    @Override
    public boolean permitsExecutionOf(ExecutionStage stage,
                                      ExecutionState state,
                                      OptimizationContext optimizationContext) {
        return this.conjuncts.isEmpty() ||
                this.conjuncts.stream().anyMatch(conjunct -> conjunct.permitsExecutionOf(stage, state, optimizationContext));
    }

    public void addConjunct(Breakpoint breakpoint) {
        assert breakpoint != null;
        this.conjuncts.add(breakpoint);
    }
}
