/*
 * Copyright 2017-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.upgrade.impl;

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cluster.ClusterEvent;
import org.onosproject.cluster.ClusterEventListener;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.MembershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.Version;
import org.onosproject.core.VersionService;
import org.onosproject.event.AbstractListenerManager;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.AtomicValue;
import org.onosproject.store.service.AtomicValueEvent;
import org.onosproject.store.service.AtomicValueEventListener;
import org.onosproject.store.service.CoordinationService;
import org.onosproject.store.service.Serializer;
import org.onosproject.upgrade.Upgrade;
import org.onosproject.upgrade.UpgradeAdminService;
import org.onosproject.upgrade.UpgradeEvent;
import org.onosproject.upgrade.UpgradeEventListener;
import org.onosproject.upgrade.UpgradeService;
import org.slf4j.Logger;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Upgrade service implementation.
 * <p>
 * This implementation uses the {@link CoordinationService} to store upgrade state in a version-agnostic primitive.
 * Upgrade state can be seen by current and future version nodes.
 */
@Component(immediate = true)
@Service
public class UpgradeManager
        extends AbstractListenerManager<UpgradeEvent, UpgradeEventListener>
        implements UpgradeService, UpgradeAdminService {

    private final Logger log = getLogger(getClass());

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VersionService versionService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoordinationService coordinationService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MembershipService membershipService;

    private Version localVersion;
    private AtomicValue<Upgrade> state;
    private final AtomicReference<Upgrade> currentState = new AtomicReference<>();
    private final AtomicValueEventListener<Upgrade> stateListener = event -> handleUpgradeEvent(event);
    private final ClusterEventListener clusterListener = event -> handleClusterEvent(event);

    @Activate
    public void activate() {
        state = coordinationService.<Upgrade>atomicValueBuilder()
                .withName("onos-upgrade-state")
                .withSerializer(Serializer.using(KryoNamespaces.API))
                .build()
                .asAtomicValue();
        localVersion = versionService.version();

        currentState.set(state.get());
        if (currentState.get() == null) {
            currentState.set(new Upgrade(localVersion, localVersion, Upgrade.Status.INACTIVE));
            state.set(currentState.get());
        }

        Upgrade upgrade = currentState.get();

        // If the upgrade state is not initialized, ensure this node matches the version of the cluster.
        if (!upgrade.status().active() && !Objects.equals(upgrade.source(), localVersion)) {
            log.error("Node version {} inconsistent with cluster version {}", localVersion, upgrade.source());
            throw new IllegalStateException("Node version " + localVersion +
                    " inconsistent with cluster version " + upgrade.source());
        }

        // If the upgrade state is initialized then check the node version.
        if (upgrade.status() == Upgrade.Status.INITIALIZED) {
            // If the source version equals the target version, attempt to update the target version.
            if (Objects.equals(upgrade.source(), upgrade.target()) && !Objects.equals(upgrade.target(), localVersion)) {
                upgrade = new Upgrade(upgrade.source(), localVersion, upgrade.status());
                currentState.set(upgrade);
                state.set(upgrade);
            }
        }

        // If the upgrade status is active, verify that the local version matches the upgrade version.
        if (upgrade.status().active() && !Objects.equals(upgrade.source(), upgrade.target())) {
            // If the upgrade source/target are not equal, validate that the node's version is consistent
            // with versions in the upgrade. There are two possibilities: that a not-yet-upgraded node is being
            // restarted, or that a node has been upgraded, so we need to check that this node is running either
            // the source or target version.
            if (!Objects.equals(localVersion, upgrade.source()) && !Objects.equals(localVersion, upgrade.target())) {
                log.error("Cannot upgrade node to version {}; Upgrade to {} already in progress",
                        localVersion, upgrade.target());
                throw new IllegalStateException("Cannot upgrade node to version " + localVersion + "; Upgrade to " +
                        upgrade.target() + " already in progress");
            }
        }

        state.addListener(stateListener);
        clusterService.addListener(clusterListener);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        state.removeListener(stateListener);
        clusterService.removeListener(clusterListener);
        log.info("Stopped");
    }

    @Override
    public boolean isUpgrading() {
        return getState().status().active();
    }

    @Override
    public Upgrade getState() {
        return currentState.get();
    }

    @Override
    public Version getVersion() {
        Upgrade upgrade = currentState.get();
        return upgrade.status().upgraded()
                ? upgrade.target()
                : upgrade.source();
    }

    @Override
    public boolean isLocalActive() {
        return localVersion.equals(getVersion());
    }

    @Override
    public boolean isLocalUpgraded() {
        Upgrade upgrade = currentState.get();
        return upgrade.status().active()
                && !upgrade.source().equals(upgrade.target())
                && localVersion.equals(upgrade.target());
    }

    @Override
    public void initialize() {
        Upgrade inactive = currentState.get();

        // If the current upgrade status is active, fail initialization.
        if (inactive.status().active()) {
            throw new IllegalStateException("Upgrade already active");
        }

        // Set the upgrade status to INITIALIZING.
        Upgrade initializing = new Upgrade(
                localVersion,
                localVersion,
                Upgrade.Status.INITIALIZING);
        if (!state.compareAndSet(inactive, initializing)) {
            throw new IllegalStateException("Concurrent upgrade modification");
        } else {
            currentState.set(initializing);

            // Set the upgrade status to INITIALIZED.
            Upgrade initialized = new Upgrade(
                    initializing.source(),
                    initializing.target(),
                    Upgrade.Status.INITIALIZED);
            if (!state.compareAndSet(initializing, initialized)) {
                throw new IllegalStateException("Concurrent upgrade modification");
            } else {
                currentState.set(initialized);
            }
        }
    }

    @Override
    public void upgrade() {
        Upgrade initialized = currentState.get();

        // If the current upgrade status is not INITIALIZED, throw an exception.
        if (initialized.status() != Upgrade.Status.INITIALIZED) {
            throw new IllegalStateException("Upgrade not initialized");
        }

        // Set the upgrade status to UPGRADING.
        Upgrade upgrading = new Upgrade(
                initialized.source(),
                initialized.target(),
                Upgrade.Status.UPGRADING);
        if (!state.compareAndSet(initialized, upgrading)) {
            throw new IllegalStateException("Concurrent upgrade modification");
        } else {
            currentState.set(upgrading);

            // Set the upgrade status to UPGRADED.
            Upgrade upgraded = new Upgrade(
                    upgrading.source(),
                    upgrading.target(),
                    Upgrade.Status.UPGRADED);
            if (!state.compareAndSet(upgrading, upgraded)) {
                throw new IllegalStateException("Concurrent upgrade modification");
            } else {
                currentState.set(upgraded);
            }
        }
    }

    @Override
    public void commit() {
        Upgrade upgraded = currentState.get();

        // If the current upgrade status is not UPGRADED, throw an exception.
        if (upgraded.status() != Upgrade.Status.UPGRADED) {
            throw new IllegalStateException("Upgrade not performed");
        }

        // Determine whether any nodes have not been upgraded to the target version.
        boolean upgradeComplete = membershipService.getGroups().size() == 1
                && membershipService.getLocalGroup().version().equals(upgraded.target());

        // If some nodes have not yet been upgraded, throw an exception.
        if (!upgradeComplete) {
            throw new IllegalStateException("Some nodes have not yet been upgraded to version " + upgraded.target());
        }

        // Set the upgrade status to COMMITTING.
        Upgrade committing = new Upgrade(
                upgraded.source(),
                upgraded.target(),
                Upgrade.Status.COMMITTING);
        if (!state.compareAndSet(upgraded, committing)) {
            throw new IllegalStateException("Concurrent upgrade modification");
        } else {
            currentState.set(committing);

            // Set the upgrade status to COMMITTED.
            Upgrade committed = new Upgrade(
                    committing.source(),
                    committing.target(),
                    Upgrade.Status.COMMITTED);
            if (!state.compareAndSet(committing, committed)) {
                throw new IllegalStateException("Concurrent upgrade modification");
            } else {
                currentState.set(committed);

                // Set the upgrade status to INACTIVE.
                Upgrade inactive = new Upgrade(
                        localVersion,
                        localVersion,
                        Upgrade.Status.INACTIVE);
                if (!state.compareAndSet(committed, inactive)) {
                    throw new IllegalStateException("Concurrent upgrade modification");
                } else {
                    currentState.set(inactive);
                }
            }
        }
    }

    @Override
    public void rollback() {
        Upgrade upgraded = currentState.get();

        // If the current upgrade status is not UPGRADED, throw an exception.
        if (upgraded.status() != Upgrade.Status.UPGRADED) {
            throw new IllegalStateException("Upgrade not performed");
        }

        // Set the upgrade status to ROLLING_BACK.
        Upgrade rollingBack = new Upgrade(
                upgraded.source(),
                upgraded.target(),
                Upgrade.Status.ROLLING_BACK);
        if (!state.compareAndSet(upgraded, rollingBack)) {
            throw new IllegalStateException("Concurrent upgrade modification");
        } else {
            currentState.set(rollingBack);

            // Set the upgrade status to ROLLED_BACK.
            Upgrade rolledBack = new Upgrade(
                    rollingBack.source(),
                    rollingBack.target(),
                    Upgrade.Status.ROLLED_BACK);
            if (!state.compareAndSet(rollingBack, rolledBack)) {
                throw new IllegalStateException("Concurrent upgrade modification");
            } else {
                currentState.set(rolledBack);
            }
        }
    }

    @Override
    public void reset() {
        Upgrade upgraded = currentState.get();

        // If the current upgrade status is not INITIALIZED or ROLLED_BACK, throw an exception.
        if (upgraded.status() != Upgrade.Status.INITIALIZED
                && upgraded.status() != Upgrade.Status.ROLLED_BACK) {
            throw new IllegalStateException("Upgrade not rolled back");
        }

        // Determine whether any nodes are still running the target version.
        boolean rollbackComplete = membershipService.getGroups().size() == 1
                && membershipService.getLocalGroup().version().equals(upgraded.source());

        // If some nodes have not yet been downgraded, throw an exception.
        if (!rollbackComplete) {
            throw new IllegalStateException("Some nodes have not yet been downgraded to version " + upgraded.source());
        }

        // Set the upgrade status to RESETTING.
        Upgrade resetting = new Upgrade(
                upgraded.source(),
                upgraded.target(),
                Upgrade.Status.RESETTING);
        if (!state.compareAndSet(upgraded, resetting)) {
            throw new IllegalStateException("Concurrent upgrade modification");
        } else {
            currentState.set(resetting);

            // Set the upgrade status to RESET.
            Upgrade reset = new Upgrade(
                    resetting.source(),
                    resetting.target(),
                    Upgrade.Status.RESET);
            if (!state.compareAndSet(resetting, reset)) {
                throw new IllegalStateException("Concurrent upgrade modification");
            } else {
                currentState.set(reset);

                // Set the upgrade status to INACTIVE.
                Upgrade inactive = new Upgrade(
                        localVersion,
                        localVersion,
                        Upgrade.Status.INACTIVE);
                if (!state.compareAndSet(reset, inactive)) {
                    throw new IllegalStateException("Concurrent upgrade modification");
                } else {
                    currentState.set(inactive);
                }
            }
        }
    }

    /**
     * Handles a cluster event.
     *
     * @param event the cluster event
     */
    protected void handleClusterEvent(ClusterEvent event) {
        // If an instance was deactivated, check whether we need to roll back the upgrade.
        if (event.type() == ClusterEvent.Type.INSTANCE_DEACTIVATED) {
            Upgrade upgrade = state.get();
            if (upgrade.status().upgraded()) {
                // Get the upgraded subset of the cluster and check whether the down node is a member
                // of the upgraded subset. If so, roll back the upgrade to tolerate the failure.
                Set<NodeId> upgradedNodes = clusterService.getNodes().stream()
                        .map(ControllerNode::id)
                        .filter(id -> clusterService.getVersion(id).equals(upgrade.target()))
                        .collect(Collectors.toSet());
                if (upgradedNodes.contains(event.subject().id())) {
                    rollback();
                }
            }
        }
    }

    /**
     * Handles an upgrade state event.
     *
     * @param event the upgrade value event
     */
    protected void handleUpgradeEvent(AtomicValueEvent<Upgrade> event) {
        currentState.set(event.newValue());
        switch (event.newValue().status()) {
            case INITIALIZED:
                post(new UpgradeEvent(UpgradeEvent.Type.INITIALIZED, event.newValue()));
                break;
            case UPGRADED:
                post(new UpgradeEvent(UpgradeEvent.Type.UPGRADED, event.newValue()));
                break;
            case COMMITTED:
                post(new UpgradeEvent(UpgradeEvent.Type.COMMITTED, event.newValue()));
                break;
            case ROLLED_BACK:
                post(new UpgradeEvent(UpgradeEvent.Type.ROLLED_BACK, event.newValue()));
                break;
            case RESET:
                post(new UpgradeEvent(UpgradeEvent.Type.RESET, event.newValue()));
                break;
            default:
                break;
        }
    }
}
