//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.deploy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jetty.deploy.graph.Graph;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/**
 * The lifecycle of an App in the {@link DeploymentManager}.
 * <p>
 * Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link AppLifeCycle.Binding}
 * annotation.
 * <p>
 * <img alt="app lifecycle graph" src="doc-files/AppLifeCycle.png">
 */
public class AppLifeCycle extends Graph
{
    private static final Logger LOG = Log.getLogger(AppLifeCycle.class);

    private static final String ALL_NODES = "*";

    public static interface Binding
    {
        /**
         * Get a list of targets that this implementation should bind to.
         * 
         * @return the array of String node names to bind to. (use <code>"*"</code> to bind to all known node names)
         */
        String[] getBindingTargets();

        /**
         * Event called to process a {@link AppLifeCycle} binding.
         * 
         * @param node
         *            the node being processed
         * @param app
         *            the app being processed
         * @throws Exception
         *             if any problem severe enough to halt the AppLifeCycle processing
         */
        void processBinding(Node node, App app) throws Exception;
    }

    // Well known existing lifecycle Nodes
    public static final String UNDEPLOYED = "undeployed";
    public static final String DEPLOYING = "deploying";
    public static final String DEPLOYED = "deployed";
    public static final String STARTING = "starting";
    public static final String STARTED = "started";
    public static final String STOPPING = "stopping";
    public static final String UNDEPLOYING = "undeploying";
    
    
    private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();

    public AppLifeCycle()
    {
        // Define Default Graph

        // undeployed -> deployed
        addEdge(UNDEPLOYED,DEPLOYING);
        addEdge(DEPLOYING,DEPLOYED);

        // deployed -> started
        addEdge(DEPLOYED,STARTING);
        addEdge(STARTING,STARTED);

        // started -> deployed
        addEdge(STARTED,STOPPING);
        addEdge(STOPPING,DEPLOYED);

        // deployed -> undeployed
        addEdge(DEPLOYED,UNDEPLOYING);
        addEdge(UNDEPLOYING,UNDEPLOYED);
    }

    public void addBinding(AppLifeCycle.Binding binding)
    {
        for (String nodeName : binding.getBindingTargets())
        {
            List<Binding> bindings = lifecyclebindings.get(nodeName);
            if (bindings == null)
            {
                bindings = new ArrayList<Binding>();
            }
            bindings.add(binding);

            lifecyclebindings.put(nodeName,bindings);
        }
    }
    
    public void removeBinding(AppLifeCycle.Binding binding)
    {
        for (String nodeName : binding.getBindingTargets())
        {
            List<Binding> bindings = lifecyclebindings.get(nodeName);
            if (bindings != null)
                bindings.remove(binding);
        }
    }

    /**
     * Get all {@link Node} bound objects.
     * 
     * @return Set of Object(s) for all lifecycle bindings. never null.
     */
    public Set<AppLifeCycle.Binding> getBindings()
    {
        Set<Binding> boundset = new HashSet<Binding>();

        for (List<Binding> bindings : lifecyclebindings.values())
        {
            boundset.addAll(bindings);
        }

        return boundset;
    }

    /**
     * Get all objects bound to a specific {@link Node}
     * 
     * @param node the deployment graph node 
     * @return Set of Object(s) for specific lifecycle bindings. never null.
     */
    public Set<AppLifeCycle.Binding> getBindings(Node node)
    {
        return getBindings(node.getName());
    }

    /**
     * Get all objects bound to a specific {@link Node}
     * 
     * @param nodeName the node name 
     * @return Set of Object(s) for specific lifecycle bindings. never null.
     */
    public Set<AppLifeCycle.Binding> getBindings(String nodeName)
    {
        Set<Binding> boundset = new HashSet<Binding>();

        // Specific node binding
        List<Binding> bindings = lifecyclebindings.get(nodeName);
        if (bindings != null)
        {
            boundset.addAll(bindings);
        }

        // Special 'all nodes' binding
        bindings = lifecyclebindings.get(ALL_NODES);
        if (bindings != null)
        {
            boundset.addAll(bindings);
        }

        return boundset;
    }

    public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
    {
        for (Binding binding : getBindings(node))
        {
            if (LOG.isDebugEnabled())
                LOG.debug("Calling " + binding.getClass().getName()+" for "+app);
            binding.processBinding(node,app);
        }
    }
}
