package org.opentosca.toscana.plugins.kubernetes.docker.image;

import java.nio.file.Path;
import java.nio.file.Paths;

import org.opentosca.toscana.core.plugin.PluginFileAccess;
import org.opentosca.toscana.core.transformation.TransformationContext;

import com.spotify.docker.client.DefaultDockerClient;
import com.spotify.docker.client.DockerCertificateException;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.DockerException;
import com.spotify.docker.client.ProgressHandler;
import com.spotify.docker.client.messages.ProgressMessage;
import org.slf4j.Logger;

public abstract class ImageBuilder implements ProgressHandler {

    protected final Logger logger;
    protected final String dockerWorkDir;
    protected final PluginFileAccess access;

    private final String tag;

    /**
     @param tag           the tag ("name") that the resulting image should have
     @param dockerWorkDir The working directory (relative to transformation root) that contains the dockerfile
     @param context       The TransformationContext used to retrieve the logger and the PluginFileAccess
     */
    public ImageBuilder(String tag, String dockerWorkDir, TransformationContext context) {
        this.tag = tag;
        this.dockerWorkDir = dockerWorkDir;
        this.access = context.getPluginFileAccess();
        this.logger = context.getLogger(getClass());
    }

    public void buildImage() throws Exception {
        DockerClient client = getDockerClient();

        Path abs = Paths.get(access.getAbsolutePath(dockerWorkDir));
        // Build the image
        String result = client.build(abs, getTag(), this);
        logger.info("Image build was successful. Image ID: {}", result);
    }

    public String getTag() {
        return tag;
    }

    public abstract void storeImage() throws Exception;

    public void cleanup() throws Exception {
        DockerClient client = getDockerClient();
        // Remove image to free the used space
        logger.info("Deleting image from local Storage");
        client.removeImage(getTag());
    }

    protected DockerClient getDockerClient() throws DockerCertificateException {
        // Initialize Docker Client
        logger.debug("Attempting to get connection to the Docker Daemon");
        return DefaultDockerClient.fromEnv().build();
    }

    @Override
    public void progress(ProgressMessage progressMessage) throws DockerException {
        String stream = progressMessage.stream();
        String error = progressMessage.error();
        String progress = progressMessage.progress();
        if (stream != null) {
            logger.info(stream.replace("\n", " "));
        }
        if (progress != null) {
            logger.trace(progress.replace("\n", " "));
        }
        if (error != null) {
            logger.error(error.replace("\n", " "));
        }
    }
}

@@ -111,16 +111,52 @@
 e.Paths;
+%0Aimport java.util.function.Consumer;
 %0A%0Aimport
@@ -2483,151 +2483,475 @@
     
-String stream = progressMessage.stream();%0A        String error = progressMessage.error(
+if (logger.isDebugEnabled())%0A            log(progressMessage.progress(), logger::trace);%0A        log(progressMessage.stream(), logger::info);%0A        log(progressMessage.error(), logger::error);%0A        log(progressMessage.status(), logger::info
 );%0A    
+%7D%0A%0A
     
-String progress = progressMessage.progress();
+private String cleanString(String s) %7B%0A        //Replace Carriage Return with newline%0A        return s.replace((char) 0x0D, (char) 0x0A);%0A    %7D%0A%0A    private void log(String s, Consumer%3CString%3E loggingFunc) %7B%0A
 %0A   
@@ -2960,21 +2960,16 @@
    if (s
-tream
  != null
@@ -2988,45 +2988,145 @@
     
-logger.info(stream.replace(%22%5Cn%22, %22 %22)
+String%5B%5D lines = s.split(%22%5Cn%22);%0A            for (String line : lines) %7B%0A                String%5B%5D cleanLine = cleanString(line).split(%22%5Cn%22
 );%0A 
@@ -3128,34 +3128,32 @@
 %22);%0A        
-%7D%0A
         
 if (progress
@@ -3144,65 +3144,82 @@
     
-if (progress != null) %7B%0A            logger.trace(progress
+for (String partialLine : cleanLine) %7B%0A                    if (partialLine
 .rep
@@ -3220,35 +3220,48 @@
 ne.replace(%22
-%5Cn
+ 
 %22, %22
- 
 %22)
-);
+.length() == 0) %7B
 %0A        %7D%0A 
@@ -3261,18 +3261,16 @@
     
-%7D%0A
         
 if (
@@ -3269,29 +3269,54 @@
     
-if (error != null) %7B%0A
+        continue;%0A                    %7D%0A      
     
@@ -3327,47 +3327,74 @@
     
+  
 logg
-er.error(error.replace(%22%5Cn%22, %22 %22));
+ingFunc.accept(partialLine);%0A                %7D%0A            %7D
 %0A   

Rework Docker build Log output (#472)