/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * 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);
    }

    /**
     * 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 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();
    }

}
