package org.checkerframework.dataflow.analysis;

import java.util.Map;
import javax.lang.model.type.TypeMirror;

/**
 * Implementation of a {@link TransferResult} with two non-exceptional store; one for the 'then'
 * edge and one for 'else'. The result of {@code getRegularStore} will be the least upper bound of
 * the two underlying stores.
 *
 * @author Stefan Heule
 * @param <S> the {@link Store} used to keep track of intermediate results
 */
public class ConditionalTransferResult<A extends AbstractValue<A>, S extends Store<S>>
        extends TransferResult<A, S> {

    private final boolean storeChanged;

    /** The 'then' result store. */
    protected S thenStore;

    /** The 'else' result store. */
    protected S elseStore;

    /**
     * Create a {@code ConditionalTransferResult} with {@code thenStore} as the resulting store if
     * the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} evaluates to {@code
     * true} and {@code elseStore} otherwise.
     *
     * <p>For the meaning of storeChanged, see {@link
     * org.checkerframework.dataflow.analysis.TransferResult#storeChanged}.
     *
     * <p><em>Exceptions</em>: If the corresponding {@link
     * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then it is assumed that no
     * special handling is necessary and the store before the corresponding {@link
     * org.checkerframework.dataflow.cfg.node.Node} will be passed along any exceptional edge.
     *
     * <p><em>Aliasing</em>: {@code thenStore} and {@code elseStore} are not allowed to be used
     * anywhere outside of this class (including use through aliases). Complete control over the
     * objects is transfered to this class.
     */
    public ConditionalTransferResult(A value, S thenStore, S elseStore, boolean storeChanged) {
        super(value);
        this.thenStore = thenStore;
        this.elseStore = elseStore;
        this.storeChanged = storeChanged;
    }

    public ConditionalTransferResult(A value, S thenStore, S elseStore) {
        this(value, thenStore, elseStore, false);
    }

    /**
     * Create a {@code ConditionalTransferResult} with {@code thenStore} as the resulting store if
     * the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} evaluates to {@code
     * true} and {@code elseStore} otherwise.
     *
     * <p><em>Exceptions</em>: If the corresponding {@link
     * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then the corresponding
     * store in {@code exceptionalStores} is used. If no exception is found in {@code
     * exceptionalStores}, then it is assumed that no special handling is necessary and the store
     * before the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} will be passed
     * along any exceptional edge.
     *
     * <p><em>Aliasing</em>: {@code thenStore}, {@code elseStore}, and any store in {@code
     * exceptionalStores} are not allowed to be used anywhere outside of this class (including use
     * through aliases). Complete control over the objects is transfered to this class.
     */
    public ConditionalTransferResult(
            A value,
            S thenStore,
            S elseStore,
            Map<TypeMirror, S> exceptionalStores,
            boolean storeChanged) {
        super(value);
        this.exceptionalStores = exceptionalStores;
        this.thenStore = thenStore;
        this.elseStore = elseStore;
        this.storeChanged = storeChanged;
    }

    public ConditionalTransferResult(
            A value, S thenStore, S elseStore, Map<TypeMirror, S> exceptionalStores) {
        this(value, thenStore, elseStore, exceptionalStores, false);
    }

    @Override
    public S getRegularStore() {
        return thenStore.leastUpperBound(elseStore);
    }

    @Override
    public S getThenStore() {
        return thenStore;
    }

    @Override
    public S getElseStore() {
        return elseStore;
    }

    @Override
    public boolean containsTwoStores() {
        return true;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("RegularTransferResult(");
        result.append(System.getProperty("line.separator"));
        result.append("resultValue = " + resultValue);
        result.append(System.getProperty("line.separator"));
        result.append("thenStore = " + thenStore);
        result.append("elseStore = " + elseStore);
        result.append(System.getProperty("line.separator"));
        result.append(")");
        return result.toString();
    }

    /** @see org.checkerframework.dataflow.analysis.TransferResult#storeChanged() */
    @Override
    public boolean storeChanged() {
        return storeChanged;
    }
}
