package net.oneandone.stool.extensions;

import net.oneandone.stool.stage.SourceStage;
import net.oneandone.stool.stage.Stage;
import net.oneandone.stool.util.Host;
import net.oneandone.stool.util.Ports;
import net.oneandone.sushi.cli.Console;
import net.oneandone.sushi.fs.file.FileNode;
import net.oneandone.sushi.util.Strings;
import net.oneandone.sushi.xml.XmlException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Fitnesse implements Extension {
    private static final String FITNESSSE_PREFIX = "fitnesse.";

    @Override
    public Map<String, FileNode> vhosts(Stage stage) throws IOException {
        Map<String, FileNode> result;

        if (!(stage instanceof SourceStage)) {
            throw new UnsupportedOperationException("stage type not supported: " + stage.getClass());
        }
        result = new HashMap<>();
        for (String vhost : stage.hosts().keySet()) {
            result.put(FITNESSSE_PREFIX + vhost, null);
        }
        return result;
    }

    @Override
    public void beforeStart(Stage stage) throws IOException {
        Console console;
        Ports ports;
        Host host;
        int port;
        String projectDir;
        String url;

        console = stage.session.console;
        ports = stage.loadPortsOpt();
        for (String vhost : stage.hosts().keySet()) {
            host = ports.lookup(FITNESSSE_PREFIX + vhost);
            projectDir = findProjectDir(ports, host);
            port = host.httpPort();
            stage.launcher("sh", projectDir + "/src/test/resources/fitnesse-start.sh", String.valueOf(port), projectDir).exec(console.info, console.error);
            url = findUrl(host);
            console.info.println("fitnesse start: " + url.concat(":" + port));
        }
    }

    private String findProjectDir(Ports ports, Host fitnesseHost) {
        String path;

        path = ports.lookup(Strings.removeLeft(fitnesseHost.vhost, FITNESSSE_PREFIX)).docBase();
        return path.substring(0, path.indexOf("/target"));
    }

    @Override
    public void beforeStop(Stage stage) throws IOException {
        Console console;
        Ports ports;
        Host host;
        int port;

        console = stage.session.console;
        ports = stage.loadPortsOpt();
        for (String vhost : stage.hosts().keySet()) {
            host = ports.lookup(FITNESSSE_PREFIX + vhost);
            port = host.httpPort();
            String url = findUrl(host);
            String projectDir = findProjectDir(ports, host);
            stage.launcher("sh", projectDir + "/src/test/resources/fitnesse-stop.sh", url, String.valueOf(port), projectDir).exec(console.info,console.error);
            console.info.println("fitnesse stop: " + url.concat(":" + port));
        }
    }

    private String findUrl(Host host) {
        return host.httpUrl(false);
    }

    @Override
    public void contextParameter(Stage stage, String host, int httpPort, FileNode webinf, Map<String, String> result) throws XmlException {
    }
}

@@ -282,16 +282,62 @@
 leNode;%0A
+import net.oneandone.sushi.launcher.Launcher;%0A
 import n
@@ -415,16 +415,37 @@
 ption;%0A%0A
+import java.io.File;%0A
 import j
@@ -1271,38 +1271,63 @@
 ing 
-projectDir;%0A        String url
+url;%0A        Launcher launcher;%0A        Process process
 ;%0A%0A 
@@ -1534,82 +1534,61 @@
    p
-rojectDir = findProjectDir(ports, host);%0A            port = host.httpPort(
+ort = host.httpPort();%0A            url = findUrl(host
 );%0A 
@@ -1589,32 +1589,43 @@
 st);%0A           
+ launcher =
  stage.launcher(
@@ -1629,133 +1629,117 @@
 er(%22
-sh%22, projectDir + %22/src/test/resources/fitnesse-start.sh%22, String.valueOf(port), projectDir).exec(console.info, console.err
+mvn%22, %22-P%22, %22fitnesse uk.co.javahelp.fitnesse:fitnesse-launcher-maven-plugin:wiki%22, %22-Dfitnesse.port=%22 + p
 or
+t
 );%0A 
@@ -1753,104 +1753,87 @@
     
-url = findUrl(host);%0A            console.info.println(%22fitnesse start: %22 + url.concat(%22:%22 + port
+launcher.getBuilder().redirectOutput(new File(%22target/fitness-%22 + port + %22.out%22
 ));%0A
@@ -1844,262 +1844,255 @@
     
-%7D%0A
     
-%7D%0A%0A    private String findProjectDir(Ports ports, Host fitnesseHost) %7B%0A        String path;%0A%0A        path = ports.lookup(Strings.removeLeft(fitnesseHost.vhost, FITNESSSE_PREFIX)).docBase();%0A        return path.substring(0, path.indexOf(%22/target%22));
+launcher.getBuilder().redirectError(new File(%22target/fitness-%22 + port + %22.err%22));%0A            process = launcher.getBuilder().start();%0A            console.info.println(%22fitnesse started (%22 + process + %22): %22 + url.concat(%22:%22 + port));%0A        %7D
 %0A   
@@ -2234,34 +2234,16 @@
 st host;
-%0A        int port;
 %0A%0A      
@@ -2444,56 +2444,32 @@
     
-port = host.httpPort();%0A            String 
+stage.launcher(%22c
 url 
-=
+%22 +
  fin
@@ -2482,305 +2482,78 @@
 ost)
-;%0A            String projectDir = findProjectDir(ports, host);%0A            stage.launcher(%22sh%22, projectDir + %22/src/test/resources/fitnesse-stop.sh%22, url, String.valueOf(port), projectDir).exec(console.info,console.error);%0A            console.info.println(%22fitnesse stop: %22 + url.concat(%22:%22 + port)
+ + %22:%22 + host.httpPort() + %22?responder=shutdown%22).exec(console.verbose
 );%0A 

update Fitnesse code