/*
 * 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.optimizer.enumeration;

import org.apache.wayang.core.api.Configuration;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

/**
 * This {@link PlanEnumerationPruningStrategy} retains only the best {@code k} {@link PlanImplementation}s.
 */
@SuppressWarnings("unused")
public class RandomPruningStrategy implements PlanEnumerationPruningStrategy {

    private Random random;

    private int numRetainedPlans;

    @Override
    public void configure(Configuration configuration) {
        this.numRetainedPlans = (int) configuration.getLongProperty("wayang.core.optimizer.pruning.random.retain", 1);
        long seed = configuration.getLongProperty("wayang.core.optimizer.pruning.random.seed", System.currentTimeMillis());
        this.random = new Random(seed);
    }

    @Override
    public void prune(PlanEnumeration planEnumeration) {
        if (planEnumeration.getPlanImplementations().size() <= this.numRetainedPlans) return;

        ArrayList<PlanImplementation> planImplementations = new ArrayList<>(planEnumeration.getPlanImplementations());
        Collections.shuffle(planImplementations, this.random);
        planEnumeration.getPlanImplementations().retainAll(planImplementations.subList(0, this.numRetainedPlans));
    }
}
