/*
 * Copyright (c) 2022 Contributors to the Eclipse Foundation
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.config.serverbeans;

import com.sun.enterprise.config.serverbeans.customvalidators.ConfigRefConstraint;
import com.sun.enterprise.config.serverbeans.customvalidators.ConfigRefValidator;
import com.sun.enterprise.config.serverbeans.customvalidators.NotDuplicateTargetName;
import com.sun.enterprise.config.serverbeans.customvalidators.NotTargetKeyword;
import com.sun.enterprise.config.serverbeans.customvalidators.ReferenceConstraint;
import com.sun.enterprise.config.util.ConfigApiLoggerInfo;
import com.sun.enterprise.config.util.InstanceRegisterInstanceCommandParameters;
import com.sun.enterprise.config.util.PortBaseHelper;
import com.sun.enterprise.config.util.PortManager;
import com.sun.enterprise.config.util.ServerHelper;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.util.net.NetUtils;

import jakarta.inject.Inject;
import jakarta.validation.Payload;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;

import java.beans.PropertyVetoException;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.api.ActionReport;
import org.glassfish.api.Param;
import org.glassfish.api.admin.AdminCommandContext;
import org.glassfish.api.admin.CommandRunner;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.api.admin.config.Named;
import org.glassfish.api.admin.config.PropertiesDesc;
import org.glassfish.api.admin.config.ReferenceContainer;
import org.glassfish.api.logging.LogHelper;
import org.glassfish.config.support.CreationDecorator;
import org.glassfish.config.support.DeletionDecorator;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.quality.ToDo;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.Attribute;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.jvnet.hk2.config.ConfigSupport;
import org.jvnet.hk2.config.Configured;
import org.jvnet.hk2.config.Dom;
import org.jvnet.hk2.config.DuckTyped;
import org.jvnet.hk2.config.Element;
import org.jvnet.hk2.config.SingleConfigCode;
import org.jvnet.hk2.config.Transaction;
import org.jvnet.hk2.config.TransactionFailure;
import org.jvnet.hk2.config.types.Property;
import org.jvnet.hk2.config.types.PropertyBag;

import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.OPERAND_NAME;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_CHECKPORTS;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_CLUSTER;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_CONFIG;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_LBENABLED;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_NODE;
import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.PARAM_PORTBASE;
import static org.glassfish.config.support.Constants.NAME_SERVER_REGEX;

/**
 * Jakarta EE Application Server Configuration
 * Each Application Server instance is a Jakarta EE compliant container.
 * One server instance is specially designated as the Administration Server in SE/EE
 * User applications cannot be deployed to an Administration Server instance
 */
@Configured
@ConfigRefConstraint(message = "{configref.invalid}", payload = ConfigRefValidator.class)
@SuppressWarnings("unused")
@NotDuplicateTargetName(message = "{server.duplicate.name}", payload = Server.class)
@ReferenceConstraint(skipDuringCreation = true, payload = Server.class)
public interface Server
    extends ConfigBeanProxy, PropertyBag, Named, SystemPropertyBag, ReferenceContainer, RefContainer, Payload {

    String lbEnabledSystemProperty = "org.glassfish.lb-enabled-default";

    @Param(name = OPERAND_NAME, primary = true)
    @Override
    void setName(String value) throws PropertyVetoException;

    @NotTargetKeyword(message = "{server.reserved.name}", payload = Server.class)
    @Pattern(regexp = NAME_SERVER_REGEX, message = "{server.invalid.name}", payload = Server.class)
    @Override
    String getName();

    /**
     * Gets the value of the configRef property.
     * Points to a named config. Needed for stand-alone servers.
     * If server instance is part of a cluster, then it points to the cluster config
     *
     * @return possible object is {@link String }
     */
    @Attribute
    @NotNull
    @NotTargetKeyword(message = "{server.reserved.name}", payload = Server.class)
    @Pattern(regexp = NAME_SERVER_REGEX, message = "Pattern: " + NAME_SERVER_REGEX)
    @ReferenceConstraint.RemoteKey(message = "{resourceref.invalid.configref}", type = Config.class)
    String getConfigRef();

    /**
     * Sets the value of the configRef property.
     *
     * @param value allowed object is {@link String }
     * @throws PropertyVetoException if a listener vetoes the change
     */
    @Param(name = PARAM_CONFIG, optional = true)
    void setConfigRef(String value) throws PropertyVetoException;

    /**
     * Gets the value of the nodeAgentRef property.
     *
     * SE/EE only. Specifies name of node agent where server instance is hosted
     *
     * @return possible object is {@link String }
     */
    @Attribute
    @Deprecated
    String getNodeAgentRef();

    /**
     * Sets the value of the nodeAgentRef property.
     *
     * @param value allowed object is {@link String }
     * @throws PropertyVetoException if a listener vetoes the change
     */
    @Deprecated
    void setNodeAgentRef(String value) throws PropertyVetoException;

    /**
     * Sets the value of the node property.
     *
     * @param value allowed object is {@link String }
     * @throws PropertyVetoException if a listener vetoes the change
     */
    @Param(name = PARAM_NODE, optional = true)
    void setNodeRef(String value) throws PropertyVetoException;

    /**
     * Gets the value of the node property.
     *
     * SE/EE only. Specifies name of node agent where server instance is hosted
     *
     * @return possible object is {@link String }
     */
    @Attribute
    String getNodeRef();

    /**
     * Gets the value of the lbWeight property.
     *
     * Each server instance in a cluster has a weight, which may be used to represent the relative processing capacity of
     * that instance. Default weight is 100 for every instance. Weighted load balancing policies will use this weight while
     * load balancing requests within the cluster. It is the responsibility of the administrator to set the relative weights
     * correctly, keeping in mind deployed hardware capacity
     *
     * @return possible object is {@link String }
     */
    @Attribute(defaultValue = "100")
    @Min(value = 1)
    String getLbWeight();

    /**
     * Sets the value of the lbWeight property.
     *
     * @param value allowed object is {@link String }
     * @throws PropertyVetoException if a listener vetoes the change
     */
    void setLbWeight(String value) throws PropertyVetoException;

    /**
     * Gets the value of the systemProperty property.
     * <p/>
     * <p/>
     * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object. This is why there is not a <CODE>set</CODE> method for the
     * systemProperty property.
     * <p/>
     * <p/>
     * For example, to add a new item, do as follows:
     *
     * <pre>
     * getSystemProperty().add(newItem);
     * </pre>
     * <p/>
     * <p/>
     * <p/>
     * Objects of the following type(s) are allowed in the list {@link SystemProperty }
     */
    @ToDo(priority = ToDo.Priority.IMPORTANT, details = "Provide PropertyDesc for legal system properties")
    @Element
    @Param(name = InstanceRegisterInstanceCommandParameters.ParameterNames.PARAM_SYSTEMPROPERTIES, optional = true)
    @Override
    List<SystemProperty> getSystemProperty();

    /**
     * Properties as per {@link PropertyBag}
     */
    @ToDo(priority = ToDo.Priority.IMPORTANT, details = "Provide PropertyDesc for legal props")
    @PropertiesDesc(props = {})
    @Element
    @Param(name = "properties", optional = true)
    @Override
    List<Property> getProperty();

    @DuckTyped
    @Override
    String getReference();

    @DuckTyped
    ResourceRef getResourceRef(String name);

    @DuckTyped
    boolean isResourceRefExists(String refName);

    @DuckTyped
    void deleteResourceRef(String name) throws TransactionFailure;

    @DuckTyped
    void createResourceRef(String enabled, String refName) throws TransactionFailure;

    @DuckTyped
    ApplicationRef getApplicationRef(String appName);

    /**
     * Returns the cluster instance this instance is referenced in or null if there is no cluster referencing this server
     * instance.
     *
     * @return the cluster owning this instance or null if this is a standalone instance
     */
    @DuckTyped
    Cluster getCluster();

    // four trivial methods that ReferenceContainer's need to implement
    @DuckTyped
    @Override
    boolean isCluster();

    @DuckTyped
    @Override
    boolean isServer();

    @DuckTyped
    @Override
    boolean isDas();

    @DuckTyped
    @Override
    boolean isInstance();

    @DuckTyped
    String getAdminHost();

    @DuckTyped
    int getAdminPort();

    @DuckTyped
    Config getConfig();

    @DuckTyped
    boolean isRunning();

    class Duck {

        public static boolean isCluster(Server server) {
            return false;
        }

        public static boolean isServer(Server server) {
            return true;
        }

        public static boolean isInstance(Server server) {
            String name = (server == null) ? null : server.getName();
            return name != null && !name.equals("server");
        }

        public static boolean isDas(Server server) {
            String name = (server == null) ? null : server.getName();
            return "server".equals(name);
        }

        public static Cluster getCluster(Server server) {
            Dom serverDom = Dom.unwrap(server);
            Clusters clusters = serverDom.getHabitat().getService(Clusters.class);
            if (clusters != null) {
                for (Cluster cluster : clusters.getCluster()) {
                    for (ServerRef serverRef : cluster.getServerRef()) {
                        if (serverRef.getRef().equals(server.getName())) {
                            return cluster;
                        }
                    }
                }
            }
            return null;
        }

        public static String getReference(Server server) {
            return server.getConfigRef();
        }

        public static ApplicationRef getApplicationRef(Server server, String appName) {
            for (ApplicationRef appRef : server.getApplicationRef()) {
                if (appRef.getRef().equals(appName)) {
                    return appRef;
                }
            }
            return null;
        }

        public static ResourceRef getResourceRef(Server server, String refName) {
            for (ResourceRef ref : server.getResourceRef()) {
                if (ref.getRef().equals(refName)) {
                    return ref;
                }
            }
            return null;
        }

        public static boolean isResourceRefExists(Server server, String refName) {
            return getResourceRef(server, refName) != null;
        }

        public static void deleteResourceRef(Server server, String refName) throws TransactionFailure {
            final ResourceRef ref = getResourceRef(server, refName);
            if (ref != null) {
                ConfigSupport.apply(new SingleConfigCode<Server>() {

                    @Override
                    public Object run(Server param) {
                        return param.getResourceRef().remove(ref);
                    }
                }, server);
            }
        }

        public static void createResourceRef(Server server, final String enabled, final String refName) throws TransactionFailure {

            ConfigSupport.apply(new SingleConfigCode<Server>() {

                @Override
                public Object run(Server param) throws PropertyVetoException, TransactionFailure {

                    ResourceRef newResourceRef = param.createChild(ResourceRef.class);
                    newResourceRef.setEnabled(enabled);
                    newResourceRef.setRef(refName);
                    param.getResourceRef().add(newResourceRef);
                    return newResourceRef;
                }
            }, server);
        }

        public static Config getConfig(Server server) {
            try {
                if (server == null) {
                    return null;
                }

                Dom serverDom = Dom.unwrap(server);
                Configs configs = serverDom.getHabitat().getService(Configs.class);
                String configName = getReference(server);
                Config theConfig = null;

                for (Config config : configs.getConfig()) {
                    if (configName.equals(config.getName())) {
                        return config;
                    }
                }
            } catch (Exception e) {
                // drop through...
            }
            return null;
        }

        public static int getAdminPort(Server server) {
            try {
                ServerHelper helper = new ServerHelper(server, getConfig(server));
                return helper.getAdminPort();
            } catch (Exception e) {
                // drop through...
            }
            return -1;
        }

        public static String getAdminHost(Server server) {
            try {
                ServerHelper helper = new ServerHelper(server, getConfig(server));
                return helper.getAdminHost();
            } catch (Exception e) {
                // drop through...
            }
            return null;
        }

        /**
         * this is NOT a reliable test. It just checks if ANYTHING has setup shop on the host and port. I wanted to run
         * RemoteAdminCommand but that is (inexplicably) in admin/util -- and we would have a circular dependency
         *
         * @param server
         * @return
         */
        public static boolean isRunning(Server server) {
            try {
                ServerHelper helper = new ServerHelper(server, getConfig(server));
                return helper.isRunning();
            } catch (Exception e) {
                // drop through...
            }
            return false;
        }
    }

    @Service
    @PerLookup
    class CreateDecorator implements CreationDecorator<Server> {

        @Param(name = PARAM_CLUSTER, optional = true)
        String clusterName;
        @Param(name = PARAM_NODE, optional = true)
        String node = null;
        @Param(name = PARAM_LBENABLED, optional = true)
        String lbEnabled = null;
        @Param(name = PARAM_CHECKPORTS, optional = true, defaultValue = "true")
        boolean checkPorts = true;
        @Param(name = PARAM_PORTBASE, optional = true)
        private String portBase;
        @Param(optional = true, defaultValue = "false", shortName = "t")
        public Boolean terse = false;
        @Inject
        Domain domain;
        @Inject
        private ServerEnvironment env;

        @Inject
        CommandRunner runner;

        @Override
        public void decorate(AdminCommandContext context, final Server instance) throws TransactionFailure, PropertyVetoException {
            Config ourConfig = null;
            Cluster ourCluster = null;
            Logger logger = ConfigApiLoggerInfo.getLogger();
            LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Server.class);
            Transaction tx = Transaction.getTransaction(instance);
            String configRef = instance.getConfigRef();
            Clusters clusters = domain.getClusters();

            if (tx == null) {
                throw new TransactionFailure(
                        localStrings.getLocalString("noTransaction", "Internal Error - Cannot obtain transaction object"));
            }

            if (node != null) {
                Node theNode = domain.getNodeNamed(node);
                if (theNode == null) {
                    throw new TransactionFailure(localStrings.getLocalString("noSuchNode", "Node {0} does not exist.", node));
                }

                /* 16034: see if instance creation is turned off on node */
                if (!theNode.instanceCreationAllowed()) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("instanceCreationNotAllowed", "Instance creation is disabled on node {0}.", node));
                }
            }

            if (portBase != null) {
                PortBaseHelper pbh = new PortBaseHelper(instance, portBase, false, logger);
                pbh.verifyPortBase();
                pbh.setPorts();
            }

            // cluster instance using cluster config
            if (clusterName != null) {
                if (configRef != null) {
                    throw new TransactionFailure(localStrings.getLocalString("Server.cannotSpecifyBothConfigAndCluster",
                            "A configuration name and cluster name cannot both be specified."));
                }
                boolean clusterExists = false;

                if (clusters != null) {
                    for (Cluster cluster : clusters.getCluster()) {
                        if (cluster != null && clusterName.equals(cluster.getName())) {
                            ourCluster = cluster;
                            String configName = cluster.getConfigRef();
                            instance.setConfigRef(configName);
                            clusterExists = true;
                            ourConfig = domain.getConfigNamed(configName);
                            break;
                        }
                    }
                }

                if (ourCluster == null) {
                    throw new TransactionFailure(localStrings.getLocalString("noSuchCluster", "Cluster {0} does not exist.", clusterName));
                }

                /*
                 * We are only setting this when the discovery uri list
                 * is set to "generate." Otherwise the user must set this
                 * properly to match the discovery uri list.
                 */
                if (ourCluster.getProperty("GMS_DISCOVERY_URI_LIST") != null
                        && "generate".equals(ourCluster.getProperty("GMS_DISCOVERY_URI_LIST").getValue())) {

                    final String propName = "GMS_LISTENER_PORT-" + ourCluster.getName();

                    /*
                     * Currently all the instances will use the same port
                     * as the DAS. When/if we move to allow more than one
                     * instance/machine, the value here will need to be
                     * calculated differently.
                     */
                    Config serverConf = domain.getConfigNamed("server-config");
                    SystemProperty dasGmsPortProp = serverConf.getSystemProperty(propName);
                    if (dasGmsPortProp != null) {
                        SystemProperty gmsListenerPortProp = instance.createChild(SystemProperty.class);
                        gmsListenerPortProp.setName(propName);
                        gmsListenerPortProp.setValue(dasGmsPortProp.getValue());
                        instance.getSystemProperty().add(gmsListenerPortProp);
                    }
                }

                final String instanceName = instance.getName();
                File configConfigDir = new File(env.getConfigDirPath(), ourCluster.getConfigRef());
                File docroot = new File(configConfigDir, "docroot");
                if (!docroot.exists() && !docroot.mkdirs()) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("noMkdir", "Cannot create configuration specific directory {0}", "docroot"));
                }
                File lib = new File(configConfigDir, "lib/ext");
                if (!lib.exists() && !lib.mkdirs()) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("noMkdir", "Cannot create configuration specific directory {0}", "lib/ext"));
                }

                Cluster c = tx.enroll(ourCluster);
                ServerRef newServerRef = c.createChild(ServerRef.class);
                newServerRef.setRef(instanceName);
                if (lbEnabled != null) {
                    newServerRef.setLbEnabled(lbEnabled);
                } else {
                    //check whether all instances in cluster had lb-enabled set to false
                    List<ServerRef> serverRefs = c.getServerRef();
                    Iterator<ServerRef> serverRefIter = serverRefs.iterator();
                    boolean allLBEnabled = false;
                    while (serverRefIter.hasNext()) {
                        ServerRef serverRef = serverRefIter.next();
                        allLBEnabled = Boolean.parseBoolean(serverRef.getLbEnabled());
                    }
                    //if there are existing instances in cluster
                    //and they all have lb-enabled to false, set it
                    //false for new instance as well
                    if (!allLBEnabled && serverRefs.size() > 0) {
                        newServerRef.setLbEnabled("false");
                    } else {
                        //check if system property exists and use that
                        String lbEnabledDefault = System.getProperty(lbEnabledSystemProperty);
                        if (lbEnabledDefault != null) {
                            newServerRef.setLbEnabled(lbEnabledDefault);
                        }
                    }
                }
                c.getServerRef().add(newServerRef);
            }

            // instance using specified config
            if (configRef != null) {
                Config specifiedConfig = domain.getConfigs().getConfigByName(configRef);
                if (specifiedConfig == null) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("noSuchConfig", "Configuration {0} does not exist.", configRef));
                }
                ourConfig = specifiedConfig;
                File configConfigDir = new File(env.getConfigDirPath(), specifiedConfig.getName());
                File docroot = new File(configConfigDir, "docroot");
                if (!docroot.exists() && !docroot.mkdirs()) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("noMkdir", "Cannot create configuration specific directory {0}", "docroot"));
                }
                File lib = new File(configConfigDir, "lib/ext");
                if (!lib.exists() && !lib.mkdirs()) {
                    throw new TransactionFailure(
                            localStrings.getLocalString("noMkdir", "Cannot create configuration specific directory {0}", "lib/ext"));
                }
            }

            //stand-alone instance using default-config if config not specified
            if (configRef == null && clusterName == null) {
                Config defaultConfig = domain.getConfigs().getConfigByName("default-config");

                if (defaultConfig == null) {
                    final String msg = localStrings.getLocalString(Server.class, "Cluster.noDefaultConfig",
                            "Can''t find the default config (an element named \"default-config\") "
                                    + "in domain.xml.  You may specify the name of an existing config element next time.");

                    logger.log(Level.SEVERE, ConfigApiLoggerInfo.noDefaultConfig);
                    throw new TransactionFailure(msg);
                }
                final String configName = instance.getName() + "-config";
                instance.setConfigRef(configName);
                final CopyConfig command = (CopyConfig) runner.getCommand("copy-config", context.getActionReport(), context.getLogger());

                Configs configs = domain.getConfigs();
                Configs writableConfigs = tx.enroll(configs);

                ourConfig = command.copyConfig(writableConfigs, defaultConfig, configName, logger);

            }

            for (Resource resource : domain.getResources().getResources()) {
                if (Resource.Duck.copyToInstance(resource)) {
                    String name = null;
                    if (resource instanceof BindableResource) {
                        name = ((BindableResource) resource).getJndiName();
                    }
                    if (resource instanceof Named) {
                        name = ((Named) resource).getName();
                    }
                    if (name == null) {
                        throw new TransactionFailure("Cannot add un-named resources to the new server instance");
                    }
                    ResourceRef newResourceRef = instance.createChild(ResourceRef.class);
                    newResourceRef.setRef(name);
                    instance.getResourceRef().add(newResourceRef);
                }
            }
            for (Application application : domain.getApplications().getApplications()) {
                if (application.getObjectType().equals("system-all") || application.getObjectType().equals("system-instance")) {
                    ApplicationRef newAppRef = instance.createChild(ApplicationRef.class);
                    newAppRef.setRef(application.getName());
                    // todo : what about virtual-servers ?
                    instance.getApplicationRef().add(newAppRef);
                }
            }

            this.addClusterRefs(ourCluster, instance);
            if (checkPorts) {

                PortManager pm = new PortManager(ourCluster, ourConfig, domain, instance);
                String message = pm.process();

                if (message != null && !terse) {
                    ActionReport report = context.getActionReport();
                    report.setMessage(message);
                }
            }

            checkAdminPort(instance, ourConfig, localStrings);
            setupSupplemental(context, instance);
        }

        private void checkAdminPort(final Server instance, final Config config, LocalStringManagerImpl localStrings)
                throws TransactionFailure {
            if (node != null) {
                Node n = domain.getNodeNamed(node);
                if (n != null) {
                    String nodeHost = n.getNodeHost();
                    if (NetUtils.isThisHostLocal(nodeHost)) { // instance on same host as DAS
                        int dasAdminPort = domain.getServerNamed("server").getAdminPort();
                        // Don't use the getAdminPort duck type method directly on the instance being created
                        int instanceAdminPort = new ServerHelper(instance, config).getAdminPort();
                        if (instanceAdminPort != -1 && dasAdminPort != -1) {
                            if (instanceAdminPort == dasAdminPort) {
                                throw new TransactionFailure(localStrings.getLocalString("Server.cannotHaveSameAdminPortAsDAS",
                                        "Cannot create an instance on the same host as DAS with the same admin port as DAS: {0}.",
                                        instanceAdminPort + ""));
                            }
                        }
                    }
                }
            }
        }

        private void setupSupplemental(AdminCommandContext context, final Server instance) {
            if (clusterName != null) {
                InstanceRegisterInstanceCommandParameters cp = new InstanceRegisterInstanceCommandParameters();
                context.getActionReport().setResultType(InstanceRegisterInstanceCommandParameters.class, cp);

                Node instNode = domain.getNodeNamed(node);

                cp.config = instance.getConfigRef();
                cp.nodehost = instNode.getNodeHost();
                cp.nodedir = instNode.getNodeDir();
                cp.installdir = instNode.getInstallDir();
                List<SystemProperty> spList = instance.getSystemProperty();

                if (spList != null) {
                    Properties p = new Properties();
                    for (SystemProperty sp : spList) {
                        p.put(sp.getName(), sp.getValue());
                    }
                    cp.systemProperties = p;
                }
            }
        }

        private void addClusterRefs(Cluster cluster, Server instance) throws TransactionFailure, PropertyVetoException {
            if (cluster != null) {
                for (ApplicationRef appRef : cluster.getApplicationRef()) {
                    if (instance.getApplicationRef(appRef.getRef()) == null) {
                        ApplicationRef newAppRef = instance.createChild(ApplicationRef.class);
                        newAppRef.setRef(appRef.getRef());
                        newAppRef.setDisableTimeoutInMinutes(appRef.getDisableTimeoutInMinutes());
                        newAppRef.setEnabled(appRef.getEnabled());
                        newAppRef.setLbEnabled(appRef.getLbEnabled());
                        newAppRef.setVirtualServers(appRef.getVirtualServers());
                        instance.getApplicationRef().add(newAppRef);
                    }
                }
                for (ResourceRef rr : cluster.getResourceRef()) {
                    if (instance.getResourceRef(rr.getRef()) == null) {
                        ResourceRef newRR = instance.createChild(ResourceRef.class);
                        newRR.setRef(rr.getRef());
                        newRR.setEnabled(rr.getEnabled());
                        instance.getResourceRef().add(newRR);
                    }
                }
            }
        }
    }

    @Service
    @PerLookup
    class DeleteDecorator implements DeletionDecorator<Servers, Server> {

        @Inject
        Configs configs;
        @Inject
        private Domain domain;
        @Inject
        private ServerEnvironment env;

        @Override
        public void decorate(AdminCommandContext context, Servers parent, final Server child)
                throws PropertyVetoException, TransactionFailure {
            final Logger logger = ConfigApiLoggerInfo.getLogger();
            LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Server.class);
            final ActionReport report = context.getActionReport();
            Transaction t = Transaction.getTransaction(parent);
            Cluster cluster = domain.getClusterForInstance(child.getName());
            boolean isStandAlone = cluster == null ? true : false;

            /* setup supplemental */
            if (!isStandAlone && env.isDas()) {
                context.getActionReport().setResultType(String.class, cluster.getName());
            }

            if (isStandAlone) { // remove config <instance>-config
                String instanceConfig = child.getConfigRef();
                final Config config = configs.getConfigByName(instanceConfig);

                // bnevins June 2010
                // don't delete the config is someone else holds a reference to it!
                if (config != null && domain.getReferenceContainersOf(config).size() > 1) {
                    return;
                }

                // bnevins September 30, 2010
                // don't delete the config if it wasn't auto-generated.
                final String autoGeneratedName = child.getName() + "-config";
                if (!autoGeneratedName.equals(instanceConfig)) {
                    return;
                }

                try {
                    if (config != null) {
                        File configConfigDir = new File(env.getConfigDirPath(), config.getName());
                        FileUtils.whack(configConfigDir);
                    }
                } catch (Exception e) {
                    // no big deal - just ignore
                }
                try {
                    if (t != null) {
                        Configs c = t.enroll(configs);
                        List<Config> configList = c.getConfig();
                        configList.remove(config);
                    }
                } catch (TransactionFailure ex) {
                    LogHelper.log(logger, Level.SEVERE, ConfigApiLoggerInfo.deleteConfigFailed, ex, instanceConfig);
                    String msg = ex.getMessage() != null ? ex.getMessage()
                            : localStrings.getLocalString("deleteConfigFailed", "Unable to remove config {0}", instanceConfig);
                    report.setMessage(msg);
                    report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                    report.setFailureCause(ex);
                    throw ex;
                }
            } else { // remove server-ref from cluster
                final String instanceName = child.getName();
                if (t != null) {
                    try {
                        Cluster c = t.enroll(cluster);

                        List<ServerRef> serverRefList = c.getServerRef();
                        ServerRef serverRef = null;

                        for (ServerRef sr : serverRefList) {
                            if (sr.getRef().equals(instanceName)) {
                                serverRef = sr;
                                break;
                            }
                        }
                        if (serverRef != null) {
                            serverRefList.remove(serverRef);
                        }
                    } catch (TransactionFailure ex) {
                        LogHelper.log(logger, Level.SEVERE, ConfigApiLoggerInfo.deleteServerRefFailed, ex, instanceName, cluster.getName());
                        String msg = ex.getMessage() != null ? ex.getMessage()
                                : localStrings.getLocalString("deleteServerRefFailed", "Unable to remove server-ref {0} from cluster {1}",
                                        instanceName, cluster.getName());
                        report.setMessage(msg);
                        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                        report.setFailureCause(ex);
                        throw ex;
                    }
                }
            }
        }
    }
}
