/*
 * Copyright 2015-present Open Networking Foundation
 *
 * Licensed 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.onosproject.net.intent;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import org.onosproject.cluster.NodeId;
import org.onosproject.store.Timestamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.intent.IntentState.*;

/**
 * A wrapper class that contains an intents, its state, and other metadata for
 * internal use.
 */
@Beta
public class IntentData { //FIXME need to make this "immutable"
                          // manager should be able to mutate a local copy while processing

    private static final Logger log = LoggerFactory.getLogger(IntentData.class);

    private final Intent intent;

    private final IntentState request; //TODO perhaps we want a full fledged object for requests
    private IntentState state;
    /**
     * Intent's user request version.
     * <p>
     * version is assigned when an Intent was picked up by batch worker
     * and added to pending map.
     */
    private final Timestamp version;
    /**
     * Intent's internal state version.
     */
    // ~= mutation count
    private int internalStateVersion;
    private NodeId origin;
    private int errorCount;

    private List<Intent> installables;

    /**
     * Creates IntentData for Intent submit request.
     *
     * @param intent to request
     * @return IntentData
     */
    public static IntentData submit(Intent intent) {
        return new IntentData(checkNotNull(intent), INSTALL_REQ);
    }

    /**
     * Creates IntentData for Intent withdraw request.
     *
     * @param intent to request
     * @return IntentData
     */
    public static IntentData withdraw(Intent intent) {
        return new IntentData(checkNotNull(intent), WITHDRAW_REQ);
    }

    /**
     * Creates IntentData for Intent purge request.
     *
     * @param intent to request
     * @return IntentData
     */
    public static IntentData purge(Intent intent) {
        return new IntentData(checkNotNull(intent), PURGE_REQ);
    }

    /**
     * Creates updated IntentData after assigning task to a node.
     *
     * @param data IntentData to update work assignment
     * @param timestamp to assign to current request
     * @param node node which was assigned to handle this request (local node id)
     * @return updated IntentData object
     */
    public static IntentData assign(IntentData data, Timestamp timestamp, NodeId node) {
        IntentData assigned = new IntentData(data, checkNotNull(timestamp));
        assigned.origin = checkNotNull(node);
        assigned.internalStateVersion++;
        return assigned;
    }

    /**
     * Creates a copy of given IntentData.
     *
     * @param data intent data to copy
     * @return copy
     */
    public static IntentData copy(IntentData data) {
        return new IntentData(data);
    }

    /**
     * Creates a copy of given IntentData, and update request version.
     *
     * @param data intent data to copy
     * @param reqVersion request version to be updated
     * @return copy
     */
    public static IntentData copy(IntentData data, Timestamp reqVersion) {
        return new IntentData(data, checkNotNull(reqVersion));
    }

    /**
     * Create a copy of IntentData in next state.
     *
     * @param data intent data to copy
     * @param nextState to transition to
     * @return next state
     */
    public static IntentData nextState(IntentData data, IntentState nextState) {
        IntentData next = new IntentData(data);
        // TODO state machine sanity check
        next.setState(checkNotNull(nextState));
        return next;
    }

    // TODO Should this be method of it's own, or
    // should nextState(*, CORRUPT) call increment error count?
    /**
     * Creates a copy of IntentData in corrupt state,
     * incrementing error count.
     *
     * @param data intent data to copy
     * @return next state
     */
    public static IntentData corrupt(IntentData data) {
        IntentData next = new IntentData(data);
        next.setState(IntentState.CORRUPT);
        next.incrementErrorCount();
        return next;
    }

    /**
     * Creates updated IntentData with compilation result.
     *
     * @param data IntentData to update
     * @param installables compilation result
     * @return updated IntentData object
     */
    public static IntentData compiled(IntentData data, List<Intent> installables) {
        return new IntentData(data, checkNotNull(installables));
    }


    /**
     * Constructor for creating IntentData representing user request.
     *
     * @param intent this metadata references
     * @param reqState request state
     */
    private IntentData(Intent intent,
                       IntentState reqState) {
        this.intent = checkNotNull(intent);
        this.request = checkNotNull(reqState);
        this.version = null;
        this.state = reqState;
        this.installables = ImmutableList.of();
    }

    /**
     * Constructor for creating updated IntentData.
     *
     * @param original IntentData to copy from
     * @param newReqVersion new request version
     */
    private IntentData(IntentData original, Timestamp newReqVersion) {
        intent = original.intent;
        state = original.state;
        request = original.request;
        version = newReqVersion;
        internalStateVersion = original.internalStateVersion;
        origin = original.origin;
        installables = original.installables;
        errorCount = original.errorCount;
    }

    /**
     * Creates a new intent data object.
     *
     * @param intent intent this metadata references
     * @param state intent state
     * @param version version of the intent for this key
     *
     * @deprecated in 1.11.0
     */
    // used to create initial IntentData (version = null)
    @Deprecated
    public IntentData(Intent intent, IntentState state, Timestamp version) {
        checkNotNull(intent);
        checkNotNull(state);

        this.intent = intent;
        this.state = state;
        this.request = state;
        this.version = version;
    }

    /**
     * Creates a new intent data object.
     *
     * @param intent intent this metadata references
     * @param state intent state
     * @param version version of the intent for this key
     * @param origin ID of the node where the data was originally created
     *
     * @deprecated in 1.11.0
     */
    // No longer used in the code base anywhere
    @Deprecated
    public IntentData(Intent intent, IntentState state, Timestamp version, NodeId origin) {
        checkNotNull(intent);
        checkNotNull(state);
        checkNotNull(version);
        checkNotNull(origin);

        this.intent = intent;
        this.state = state;
        this.request = state;
        this.version = version;
        this.origin = origin;
    }

    /**
     * Creates a new intent data object.
     *
     * @param intent intent this metadata references
     * @param state intent state
     * @param request intent request
     * @param version version of the intent for this key
     * @param origin ID of the node where the data was originally created
     *
     * @deprecated in 1.11.0
     */
    // No longer used in the code base anywhere
    // was used when IntentData is picked up by some of the node and was assigned with a version
    @Deprecated
    public IntentData(Intent intent, IntentState state, IntentState request, Timestamp version, NodeId origin) {
        checkNotNull(intent);
        checkNotNull(state);
        checkNotNull(request);
        checkNotNull(version);
        checkNotNull(origin);

        this.intent = intent;
        this.state = state;
        this.request = request;
        this.version = version;
        this.origin = origin;
    }

    /**
     * Copy constructor.
     *
     * @param intentData intent data to copy
     *
     * @deprecated in 1.11.0 use {@link #copy(IntentData)} instead
     */
    // used to create a defensive copy
    // to be made private
    @Deprecated
    public IntentData(IntentData intentData) {
        checkNotNull(intentData);

        intent = intentData.intent;
        state = intentData.state;
        request = intentData.request;
        version = intentData.version;
        internalStateVersion = intentData.internalStateVersion;
        origin = intentData.origin;
        installables = intentData.installables;
        errorCount = intentData.errorCount;
    }

    /**
     * Create a new instance based on the original instance with new installables.
     *
     * @param original original data
     * @param installables new installable intents to set
     *
     * @deprecated in 1.11.0 use {@link #compiled(IntentData, List)} instead
     */
    // used to create an instance who reached stable state
    // note that state is mutable field, so it gets altered else where
    // (probably that design is mother of all intent bugs)
    @Deprecated
    public IntentData(IntentData original, List<Intent> installables) {
        this(original);
        this.internalStateVersion++;

        this.installables = checkNotNull(installables).isEmpty() ?
                      ImmutableList.of() : ImmutableList.copyOf(installables);
    }

    // kryo constructor
    protected IntentData() {
        intent = null;
        request = null;
        version = null;
    }

    /**
     * Returns the intent this metadata references.
     *
     * @return intent
     */
    public Intent intent() {
        return intent;
    }

    /**
     * Returns the state of the intent.
     *
     * @return intent state
     */
    public IntentState state() {
        return state;
    }

    public IntentState request() {
        return request;
    }

    /**
     * Returns the intent key.
     *
     * @return intent key
     */
    public Key key() {
        return intent.key();
    }

    /**
     * Returns the request version of the intent for this key.
     *
     * @return intent version
     */
    public Timestamp version() {
        return version;
    }

    // had to be made public for the store timestamp provider
    public int internalStateVersion() {
        return internalStateVersion;
    }

    /**
     * Returns the origin node that created this intent.
     *
     * @return origin node ID
     */
    public NodeId origin() {
        return origin;
    }

    /**
     * Updates the state of the intent to the given new state.
     *
     * @param newState new state of the intent
     */
    public void setState(IntentState newState) {
        this.internalStateVersion++;
        this.state = newState;
    }

    /**
     * Increments the error count for this intent.
     */
    public void incrementErrorCount() {
        errorCount++;
    }

    /**
     * Sets the error count for this intent.
     *
     * @param newCount new count
     */
    public void setErrorCount(int newCount) {
        errorCount = newCount;
    }

    /**
     * Returns the number of times that this intent has encountered an error
     * during installation or withdrawal.
     *
     * @return error count
     */
    public int errorCount() {
        return errorCount;
    }

    /**
     * Returns the installables associated with this intent.
     *
     * @return list of installable intents
     */
    public List<Intent> installables() {
        return installables != null ? installables : Collections.emptyList();
    }

    /**
     * Determines whether an intent data update is allowed. The update must
     * either have a higher version than the current data, or the state
     * transition between two updates of the same version must be sane.
     *
     * @param currentData existing intent data in the store
     * @param newData new intent data update proposal
     * @return true if we can apply the update, otherwise false
     */
    public static boolean isUpdateAcceptable(IntentData currentData, IntentData newData) {

        if (currentData == null) {
            return true;
        } else if (currentData.version().isOlderThan(newData.version())) {
            return true;
        } else if (currentData.version().isNewerThan(newData.version())) {
            log.trace("{} update not acceptable: current is newer", newData.key());
            return false;
        }

        assert (currentData.version().equals(newData.version()));
        if (currentData.internalStateVersion >= newData.internalStateVersion) {
            log.trace("{} update not acceptable: current is newer internally", newData.key());
            return false;
        }

        // current and new data versions are the same
        IntentState currentState = currentData.state();
        IntentState newState = newData.state();

        switch (newState) {
        case INSTALLING:
            if (currentState == INSTALLING) {
                log.trace("{} update not acceptable: no-op INSTALLING", newData.key());
                return false;
            }
            // FALLTHROUGH
        case REALLOCATING:
            if (currentState == REALLOCATING) {
                log.trace("{} update not acceptable: no-op REALLOCATING", newData.key());
                return false;
            } else if (currentState == INSTALLED) {
                return true;
            }
            // FALLTHROUGH
        case INSTALLED:
            if (currentState == INSTALLED) {
                return false;
            } else if (currentState == WITHDRAWING || currentState == WITHDRAWN
                    || currentState == PURGE_REQ) {
                log.warn("Invalid state transition from {} to {} for intent {}",
                         currentState, newState, newData.key());
                return false;
            }
            return true;

        case WITHDRAWING:
            if (currentState == WITHDRAWING) {
                log.trace("{} update not acceptable: no-op WITHDRAWING", newData.key());
                return false;
            }
            // FALLTHROUGH
        case WITHDRAWN:
            if (currentState == WITHDRAWN) {
                log.trace("{} update not acceptable: no-op WITHDRAWN", newData.key());
                return false;
            } else if (currentState == INSTALLING || currentState == INSTALLED
                    || currentState == PURGE_REQ) {
                log.warn("Invalid state transition from {} to {} for intent {}",
                         currentState, newState, newData.key());
                return false;
            }
            return true;

        case FAILED:
            if (currentState == FAILED) {
                log.trace("{} update not acceptable: no-op FAILED", newData.key());
                return false;
            }
            return true;

        case CORRUPT:
            if (currentState == CORRUPT) {
                log.trace("{} update not acceptable: no-op CORRUPT", newData.key());
                return false;
            }
            return true;

        case PURGE_REQ:
            // TODO we should enforce that only WITHDRAWN intents can be purged
            return true;

        case COMPILING:
        case RECOMPILING:
        case INSTALL_REQ:
        case WITHDRAW_REQ:
        default:
            log.warn("Invalid state {} for intent {}", newState, newData.key());
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hash(intent, version);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final IntentData other = (IntentData) obj;
        return Objects.equals(this.intent, other.intent)
                && Objects.equals(this.version, other.version);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("key", key())
                .add("state", state())
                .add("version", version())
                .add("internalStateVersion", internalStateVersion)
                .add("intent", intent())
                .add("origin", origin())
                .add("installables", installables())
                .toString();
    }

}
