/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.sling.maven.kickstart.run;

import java.io.File;
import java.io.Serializable;

/**
 * A server configuration
 */
public class ServerConfiguration implements Serializable {

    private static final long serialVersionUID = 1922175510880318125L;

    private static final String DEFAULT_VM_OPTS = "-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true";

    // http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation
    private static final String DEFAULT_VM_DEBUG_OPTS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000";

    /** The unique id. */
    private String id;

    /** The run mode string. */
    private String runmode;

    /** The port to use. */
    private String port;

    /** The control port to use. */
    private String controlPort;

    /** The context path. */
    private String contextPath;

    /** The vm options. */
    private String vmOpts = DEFAULT_VM_OPTS;

    /** 
     * If set to {@code "true"}, the process will allow a debugger to connect on port 8000. 
     * If set to some other string, that string will be appended to this server's {@code vmOpts}, allowing you to configure arbitrary debugging options.
     * If the global configuration property {@link StartMojo#debug} is set on the mojo itself, it will be used instead.
     */
    private String debug;

    /** Additional application options. */
    private String opts;

    /** Number of instances. */
    private int instances = 1;

    /** The folder to use. */
    private File folder;
    
    /**
     * The relative filename of the file which receives both the standard output (stdout) and standard error (stderr) of the server processes. 
     * If null or empty string the server process inherits stdout from the parent process (i.e. the Maven process).
     * The given filename must be relative to the working directory of the according server.
     */
    private String stdOutFile;

    private File additionalFeatureFile;

    /**
     * Get the instance id
     * @return The instance id
     */
    public String getId() {
        return id;
    }

    /**
     * Set the instance id
     * @param id New instance id
     */
    public void setId(String id) {
        this.id = id;
    }

    public String getRunmode() {
        return runmode;
    }

    public void setRunmode(final String runmode) {
        this.runmode = runmode;
    }

    public String getPort() {
        return port;
    }

    public void setPort(final String port) {
        this.port = port;
    }

    public String getContextPath() {
        return contextPath;
    }

    public void setContextPath(final String contextPath) {
        this.contextPath = contextPath;
    }

    public String getVmOpts() {
        return vmOpts;
    }

    public void setVmOpts(final String vmOpts) {
        this.vmOpts = vmOpts;
    }

    /**
     * Returns the debugging options derived from the passed globalDebug parameter and the debug field (where the globalDebug parameter has precedence over the local field)
     * @param globalDebug the global debug options (may be {@code null}).
     * @return the debugging options to use or {@code null}. Should be appended to the ones being returned by {@link #getVmOpts()}.
     * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation">JPDA Sun VM Invocation Options</a>
     */
    public String getVmDebugOpts(String globalDebug) {
        if (globalDebug != null) {
            if (Boolean.valueOf(globalDebug).equals(Boolean.TRUE)) {
                return DEFAULT_VM_DEBUG_OPTS;
            }
            return globalDebug;
        }
        if (Boolean.valueOf(debug).equals(Boolean.TRUE)) {
            return DEFAULT_VM_DEBUG_OPTS;
        }
        return debug;
    }

    public void setDebug(final String debug) {
        this.debug = debug;
    }

    public String getOpts() {
        return opts;
    }

    public void setOpts(final String opts) {
        this.opts = opts;
    }

    public int getInstances() {
        return this.instances;
    }

    public void setInstances(final int value) {
        this.instances = value;
    }

    public File getFolder() {
        return folder;
    }

    public void setFolder(final File folder) {
        this.folder = folder.getAbsoluteFile();
    }

    public String getControlPort() {
        return controlPort;
    }

    public void setControlPort(String controlPort) {
        this.controlPort = controlPort;
    }

    public String getStdOutFile() {
        return stdOutFile;
    }

    public void setStdOutFile(String stdOutFile) {
        this.stdOutFile = stdOutFile;
    }

    public File getAdditionalFeatureFile() {
        return additionalFeatureFile;
    }

    public void setAdditionalFeatureFile(File additionalFeatureFile) {
        this.additionalFeatureFile = additionalFeatureFile;
    }

    /**
     * Get the server
     * @return The server
     */
    public String getServer() {
        // hard coded for now
        return "localhost";
    }

    public ServerConfiguration copy() {
        final ServerConfiguration copy = new ServerConfiguration();
        // we do not copy the id
        copy.setRunmode(this.getRunmode());
        copy.setPort(this.getPort());
        copy.setContextPath(this.getContextPath());
        copy.setVmOpts(this.getVmOpts());
        copy.setDebug(this.debug);
        copy.setOpts(this.getOpts());
        copy.setInstances(1);
        copy.setFolder(this.getFolder());
        copy.setControlPort(this.getControlPort());
        copy.setStdOutFile(this.stdOutFile);
        copy.setAdditionalFeatureFile(this.additionalFeatureFile);
        return copy;
    }

    @Override
    public String toString() {
        return "ServerConfiguration{" +
            "id='" + id + '\'' +
            ", runmode='" + runmode + '\'' +
            ", port='" + port + '\'' +
            ", controlPort='" + controlPort + '\'' +
            ", contextPath='" + contextPath + '\'' +
            ", vmOpts='" + vmOpts + '\'' +
            ", debug='" + debug + '\'' +
            ", opts='" + opts + '\'' +
            ", instances=" + instances +
            ", folder=" + folder +
            ", stdOutFile='" + stdOutFile + '\'' +
            ", additionalFeatureFile=" + additionalFeatureFile +
            '}';
    }
}
