/*
 * Copyright 2013 Twitter, Inc. and other contributors.
 * 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.jenkinsci.plugins.mesos;

import hudson.Extension;
import hudson.model.Computer;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson;
import hudson.model.Slave;
import hudson.slaves.NodeProperty;
import hudson.slaves.ComputerLauncher;

import java.io.IOException;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.kohsuke.stapler.DataBoundConstructor;

public class MesosSlave extends Slave {

  private final double cpus;
  private final int mem;

  private static final Logger LOGGER = Logger.getLogger(MesosSlave.class
      .getName());

  @DataBoundConstructor
  public MesosSlave(String name, int numExecutors, String labelString,
      double slaveCpus, int slaveMem, double executorCpus, int executorMem,
      int idleTerminationMinutes) throws FormException, IOException
  {
    super(name,
          labelString, // node description.
          "jenkins",   // remoteFS.
          "" + numExecutors,
          Mode.NORMAL,
          labelString, // Label.
          new MesosComputerLauncher(name),
          new MesosRetentionStrategy(idleTerminationMinutes),
          Collections.<NodeProperty<?>> emptyList());

    this.cpus = slaveCpus + (numExecutors * executorCpus);
    this.mem = slaveMem + (numExecutors * executorMem);

    LOGGER.info("Constructing Mesos slave");
  }

  public double getCpus() {
    return cpus;
  }

  public int getMem() {
    return mem;
  }

  public void terminate() {
    LOGGER.info("Terminating slave " + getNodeName());
    try {
      // Remove the node from hudson.
      Hudson.getInstance().removeNode(this);

      ComputerLauncher launcher = getLauncher();

      // If this is a mesos computer launcher, terminate the launcher.
      if (launcher instanceof MesosComputerLauncher) {
        ((MesosComputerLauncher) launcher).terminate();
      }
    } catch (IOException e) {
      LOGGER.log(Level.WARNING, "Failed to terminate Mesos instance: "
          + getInstanceId(), e);
    }
  }

  @Override
  public DescriptorImpl getDescriptor() {
    return (DescriptorImpl) super.getDescriptor();
  }

  @Extension
  public static class DescriptorImpl extends SlaveDescriptor {
    @Override
    public String getDisplayName() {
      return "Mesos Slave";
    }
  }

  private String getInstanceId() {
    return getNodeName();
  }

  public void idleTimeout() {
    LOGGER.info("Mesos instance idle time expired: " + getInstanceId()
        + ", terminate now");
    terminate();
  }

  @Override
  public Computer createComputer() {
    return new MesosComputer(this);
  }
}

@@ -670,24 +670,48 @@
 .Extension;%0A
+import hudson.FilePath;%0A
 import hudso
@@ -3257,11 +3257,634 @@
 is);%0A  %7D
+%0A%0A  @Override%0A  public FilePath getRootPath() %7B%0A    FilePath rootPath = createPath(remoteFS);%0A    if (rootPath != null) %7B%0A      try %7B%0A        // Construct absolute path for slave's remote file system root.%0A        rootPath = rootPath.absolutize();%0A      %7D catch (IOException e) %7B%0A        LOGGER.warning(%22IO exception while absolutizing slave root path: %22 +e);%0A      %7D catch (InterruptedException e) %7B%0A        LOGGER.warning(%22InterruptedException while absolutizing slave root path: %22 +e);%0A      %7D%0A    %7D%0A    // Return root path even if we caught an exception,%0A    // let the caller handle the error.%0A    return rootPath;%0A  %7D
 %0A%7D%0A

Fix for https://github.com/jenkinsci/mesos-plugin/issues/10 Return absolute path instead of relative path for slave file system root.