/*
 * 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.ignite.internal.processors.cluster;

import java.io.Serializable;
import java.util.Set;
import java.util.UUID;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;

/**
 * A pojo-object representing current cluster global state. The state includes cluster active flag and cluster
 * baseline topology.
 * <p>
 * This object also captures a transitional cluster state, when one or more fields are changing. In this case,
 * a {@code transitionReqId} field is set to a non-null value and {@code previousBaselineTopology} captures previous cluster state.
 * A joining node catching the cluster in an intermediate state will observe {@code transitionReqId} field to be
 * non-null, however the {@code previousBaselineTopology} will not be sent to the joining node.
 *
 * TODO https://issues.apache.org/jira/browse/IGNITE-7640 This class must be immutable, transitionRes must be set by calling finish().
 */
public class DiscoveryDataClusterState implements Serializable {
    /** */
    private static final long serialVersionUID = 0L;

    /** Flag indicating if the cluster in in active state. */
    private final boolean active;

    /** Current cluster baseline topology. */
    @Nullable private final BaselineTopology baselineTopology;

    /**
     * Transition request ID. Set to a non-null value if the cluster is changing it's state.
     * The ID is assigned on the initiating node.
     */
    private final UUID transitionReqId;

    /**
     * Topology version in the cluster when state change request was received by the coordinator.
     * The exchange fired for the cluster state change will be on version {@code transitionTopVer.nextMinorVersion()}.
     */
    @GridToStringInclude
    private final AffinityTopologyVersion transitionTopVer;

    /** Nodes participating in state change exchange. */
    @GridToStringExclude
    private final Set<UUID> transitionNodes;

    /**
     * Local flag for state transition active state result (global state is updated asynchronously by custom message),
     * {@code null} means that state change is not completed yet.
     */
    private transient volatile Boolean transitionRes;

    /**
     * Previous cluster state if this state is a transition state and it was not received by a joining node.
     */
    private transient DiscoveryDataClusterState prevState;

    /** Transition result error. */
    private transient volatile Exception transitionError;

    /**
     * @param active Current status.
     * @return State instance.
     */
    static DiscoveryDataClusterState createState(boolean active, @Nullable BaselineTopology baselineTopology) {
        return new DiscoveryDataClusterState(null, active, baselineTopology, null, null, null);
    }

    /**
     * @param active New status.
     * @param transitionReqId State change request ID.
     * @param transitionTopVer State change topology version.
     * @param transitionNodes Nodes participating in state change exchange.
     * @return State instance.
     */
    static DiscoveryDataClusterState createTransitionState(
        DiscoveryDataClusterState prevState,
        boolean active,
        @Nullable BaselineTopology baselineTopology,
        UUID transitionReqId,
        AffinityTopologyVersion transitionTopVer,
        Set<UUID> transitionNodes
    ) {
        assert transitionReqId != null;
        assert transitionTopVer != null;
        assert !F.isEmpty(transitionNodes) : transitionNodes;
        assert prevState != null;

        return new DiscoveryDataClusterState(
            prevState,
            active,
            baselineTopology,
            transitionReqId,
            transitionTopVer,
            transitionNodes);
    }

    /**
     * @param prevState Previous state. May be non-null only for transitional states.
     * @param active New state.
     * @param transitionReqId State change request ID.
     * @param transitionTopVer State change topology version.
     * @param transitionNodes Nodes participating in state change exchange.
     */
    private DiscoveryDataClusterState(
        DiscoveryDataClusterState prevState,
        boolean active,
        @Nullable BaselineTopology baselineTopology,
        @Nullable UUID transitionReqId,
        @Nullable AffinityTopologyVersion transitionTopVer,
        @Nullable Set<UUID> transitionNodes
    ) {
        this.prevState = prevState;
        this.active = active;
        this.baselineTopology = baselineTopology;
        this.transitionReqId = transitionReqId;
        this.transitionTopVer = transitionTopVer;
        this.transitionNodes = transitionNodes;
    }

    /**
     * @return Local flag for state transition result (global state is updated asynchronously by custom message).
     */
    @Nullable public Boolean transitionResult() {
        return transitionRes;
    }

    /**
     * Discovery cluster state is changed asynchronously by discovery message, this methods changes local status
     * for public API calls.
     *
     * @param reqId Request ID.
     * @param active New cluster state.
     */
    public void setTransitionResult(UUID reqId, boolean active) {
        if (reqId.equals(transitionReqId))
            transitionRes = active;
    }

    /**
     * @return State change request ID.
     */
    public UUID transitionRequestId() {
        return transitionReqId;
    }

    /**
     * @return {@code True} if any cluster state change is in progress (e.g. active state change, baseline change).
     */
    public boolean transition() {
        return transitionReqId != null;
    }

    /**
     * @return State change exchange version.
     */
    public AffinityTopologyVersion transitionTopologyVersion() {
        return transitionTopVer;
    }

    /**
     * @return Current cluster state (or new state in case when transition is in progress).
     */
    public boolean active() {
        return active;
    }

    /**
     * @return Baseline topology.
     */
    @Nullable public BaselineTopology baselineTopology() {
        return baselineTopology;
    }

    /**
     * @return Previous Baseline topology.
     */
    @Nullable public BaselineTopology previousBaselineTopology() {
        return prevState != null ? prevState.baselineTopology() : null;
    }

    /**
     *
     * @return {@code True} If baseLine changed, {@code False} if not.
     */
    public boolean baselineChanged() {
        BaselineTopology prevBLT = previousBaselineTopology();
        BaselineTopology curBLT = baselineTopology();

        if (prevBLT == null && curBLT != null)
            return true;

        if (prevBLT!= null && curBLT != null)
            return !prevBLT.equals(curBLT);

        return false;
    }

    /**
     * @return {@code True} if baseline topology is set in the cluster. {@code False} otherwise.
     */
    public boolean hasBaselineTopology() {
        return baselineTopology != null;
    }

    /**
     * @return Nodes participating in state change exchange.
     */
    public Set<UUID> transitionNodes() {
        return transitionNodes;
    }

    /**
     * @return Transition error.
     */
    @Nullable public Exception transitionError() {
        return transitionError;
    }

    /**
     * @param ex Exception
     */
    public void transitionError(Exception ex) {
        transitionError = ex;
    }

    /**
     * Creates a non-transitional cluster state. This method effectively cleans all fields identifying the
     * state as transitional and creates a new state with the state transition result.
     *
     * @param success Transition success status.
     * @return Cluster state that finished transition.
     */
    public DiscoveryDataClusterState finish(boolean success) {
        return success ?
            new DiscoveryDataClusterState(
                null,
                active,
                baselineTopology,
                null,
                null,
                null
            ) :
            prevState != null ? prevState :
                    DiscoveryDataClusterState.createState(false, null);
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(DiscoveryDataClusterState.class, this);
    }
}
