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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.wayang.core.plan.wayangplan.Operator;
import org.apache.wayang.core.platform.Platform;

/**
 * A subplan match correlates a {@link SubplanPattern} with its actually matched .
 */
public class SubplanMatch {

    /**
     * The atcual operators that have been matched to the {@link #pattern}.
     */
    private final Map<String, OperatorMatch> operatorMatches = new HashMap<>();

    /**
     * <i>Lazily initialized.</i> {@link Platform} restrictions coming from the matched {@link Operator}s.
     */
    private Optional<Set<Platform>> targetPlatforms = null;

    /**
     * The pattern that has been matched.
     */
    private final SubplanPattern pattern;

    public SubplanMatch(SubplanPattern pattern) {
        this.pattern = pattern;
    }

    /**
     * Copy constructor.
     */
    public SubplanMatch(SubplanMatch that) {
        this.pattern = that.pattern;
        this.operatorMatches.putAll(that.operatorMatches);
    }

    public void addOperatorMatch(OperatorMatch operatorMatch) {
        String name = operatorMatch.getPattern().getName();
        if (this.operatorMatches.containsKey(name)) {
            throw new IllegalArgumentException(String.format("Cannot insert operator match named \"%s\": " +
                    "a match with that name already exists.", name));
        }
        this.operatorMatches.put(name, operatorMatch);
    }

    public Map<String, OperatorMatch> getOperatorMatches() {
        return this.operatorMatches;
    }

    public SubplanPattern getPattern() {
        return this.pattern;
    }

    public OperatorMatch getInputMatch() {
        final String name = this.pattern.getInputPattern().getName();
        return this.operatorMatches.get(name);
    }

    public OperatorMatch getOutputMatch() {
        final String name = this.pattern.getOutputPattern().getName();
        return this.operatorMatches.get(name);
    }

    public OperatorMatch getMatch(String name) {
        return this.operatorMatches.get(name);
    }

    /**
     * @return the maximum epoch among the matched operators in {@link #operatorMatches}
     */
    public int getMaximumEpoch() {
        return this.operatorMatches.values().stream()
                .map(OperatorMatch::getOperator)
                .filter(Operator::isElementary)
                .mapToInt(Operator::getEpoch)
                .max()
                .orElse(Operator.FIRST_EPOCH);
    }

    /**
     * {@link Platform} restrictions coming from the matched {@link Operator}s. Notice that the semantics of empty
     * {@link Set}s differ from those in {@link Operator#getTargetPlatforms()}.
     *
     * @return the intersection of all {@link Platform} restrictions in the matched {@link Operator}s
     */
    public Optional<Set<Platform>> getTargetPlatforms() {
        if (this.targetPlatforms == null) {
            this.targetPlatforms = this.operatorMatches.values().stream()
                    .map(OperatorMatch::getOperator)
                    .map(Operator::getTargetPlatforms)
                    .filter(platforms -> !platforms.isEmpty())
                    .reduce((platforms1, platforms2) -> {
                        Set<Platform> platforms = new HashSet<>(platforms1);
                        platforms.retainAll(platforms2);
                        return platforms;
                    });
        }
        return this.targetPlatforms;
    }
}
