/*
 * Copyright 2014, Kaazing Corporation. All rights reserved.
 *
 * 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.kaazing.k3po.maven.plugin.internal;

import static java.lang.String.format;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.identityHashCode;
import static org.apache.maven.plugins.annotations.LifecyclePhase.PRE_INTEGRATION_TEST;
import static org.apache.maven.plugins.annotations.ResolutionScope.TEST;
import static org.jboss.netty.logging.InternalLoggerFactory.setDefaultFactory;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.List;

import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.kaazing.k3po.driver.internal.RobotServer;
import org.kaazing.k3po.maven.plugin.internal.logging.MavenLoggerFactory;

/**
 * Start K3PO
 */
@Mojo(name = "start", defaultPhase = PRE_INTEGRATION_TEST, requiresDependencyResolution = TEST)
public class StartMojo extends AbstractMojo {

    @Parameter(defaultValue = "true", property = "maven.k3po.daemon")
    private boolean daemon;

    @Parameter(name = "control", defaultValue = "tcp://localhost:11642")
    private URI controlURI;

    @Parameter(defaultValue = "src/test/scripts")
    private File scriptDir;

    @Parameter(defaultValue = "false", property = "maven.k3po.verbose")
    private boolean verbose;

    public URI getControl() {
        return controlURI;
    }

    public void setControl(URI controlURI) {
        this.controlURI = controlURI;
    }

    @Override
    protected void executeImpl() throws MojoExecutionException {

        try {
            ClassLoader scriptLoader = createScriptLoader();

            RobotServer server = new RobotServer(getControl(), verbose, scriptLoader);

            // TODO: detect Maven version to determine logger factory
            //         3.0 -> MavenLoggerFactory
            //         3.1 -> Slf4JLoggerFactory
            // see http://brettporter.wordpress.com/2010/10/05/creating-a-custom-build-extension-for-maven-3-0/

            // note: using SLf4J for Robot breaks in Maven 3.0 at runtime
            // setDefaultFactory(new Slf4JLoggerFactory());

            // use Maven3 logger for Robot when started via plugin
            setDefaultFactory(new MavenLoggerFactory(getLog()));

            long checkpoint = currentTimeMillis();
            server.start();
            float duration = (currentTimeMillis() - checkpoint) / 1000.0f;
            if (getLog().isDebugEnabled()) {
                getLog().debug(format("K3PO [%08x] started in %.3fsec", identityHashCode(server), duration));
            } else {
                getLog().info("K3PO started");
            }

            setServer(server);

            if (!daemon) {
                server.join();
            } else {
                getLog().info(format("K3PO will terminate when Maven process terminates"));
            }
        }
        catch (Exception e) {
            throw new MojoExecutionException("K3PO failed to start", e);
        }
    }

    private ClassLoader createScriptLoader()
            throws DependencyResolutionRequiredException, MalformedURLException {
        List<URL> scriptPath = new LinkedList<>();
        if (scriptDir != null) {
            scriptPath.add(scriptDir.getAbsoluteFile().toURI().toURL());
        }
        for (Object scriptPathEntry : project.getTestClasspathElements()) {
            URI scriptPathURI = new File(scriptPathEntry.toString()).getAbsoluteFile().toURI();
            scriptPath.add(scriptPathURI.toURL());
        }

        ClassLoader parent = getClass().getClassLoader();
        return new URLClassLoader(scriptPath.toArray(new URL[scriptPath.size()]), parent);
    }
}

@@ -1350,32 +1350,76 @@
 utionException;%0A
+import org.apache.maven.plugin.logging.Log;%0A
 import org.apach
@@ -3063,16 +3063,48 @@
  plugin%0A
+            Log log = getLog();%0A
         
@@ -3148,24 +3148,19 @@
 Factory(
-getLog()
+log
 ));%0A%0A   
@@ -3326,24 +3326,19 @@
     if (
-getLog()
+log
 .isDebug
@@ -3366,24 +3366,54 @@
         
-getLog()
+if (!daemon) %7B%0A                    log
 .debug(f
@@ -3449,16 +3449,33 @@
  %25.3fsec
+ (CTRL+C to stop)
 %22, ident
@@ -3511,33 +3511,53 @@
 ));%0A            
-%7D
+    %7D%0A               
  else %7B%0A        
@@ -3568,39 +3568,104 @@
     
-getLog().info(%22K3PO started%22);%0A
+    log.debug(format(%22K3PO %5B%2508x%5D started in %25.3fsec%22, identityHashCode(server), duration));%0A   
     
@@ -3664,34 +3664,34 @@
 %0A               
+ 
 %7D
-%0A
 %0A            set
@@ -3691,28 +3691,21 @@
     
-setServer(server);%0A%0A
+%7D else %7B%0A    
     
@@ -3747,133 +3747,262 @@
     
-server.join();%0A            %7D else %7B%0A                getLog().info(format(%22K3PO will terminate when Maven process terminates%22)
+    log.info(%22K3PO started (CTRL+C to stop)%22);%0A                %7D%0A                else %7B%0A                    log.info(%22K3PO started%22);%0A                %7D%0A            %7D%0A%0A            setServer(server);%0A%0A            if (!daemon) %7B%0A                server.join(
 );%0A 

Improve K3PO started message for daemon vs non-daemon mode