/*
 * Copyright (C) 2017 Original Authors
 *
 * 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.csanchez.jenkins.plugins.kubernetes.pipeline;

import hudson.model.TaskListener;
import hudson.util.LogTaskListener;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.dsl.LogWatch;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.dsl.PrettyLoggable;
import io.fabric8.kubernetes.client.dsl.TailPrettyLoggable;
import io.fabric8.kubernetes.client.dsl.TimeTailPrettyLoggable;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution;

import java.io.PrintStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ContainerLogStepExecution extends SynchronousNonBlockingStepExecution<String> {
    private static final long serialVersionUID = 5588861066775717487L;
    private static final transient Logger LOGGER = Logger.getLogger(ContainerLogStepExecution.class.getName());

    private final ContainerLogStep step;
    private transient KubernetesClient client;

    ContainerLogStepExecution(ContainerLogStep step, StepContext context) {
        super(context);
        this.step = step;
    }

    private PrintStream logger() {
        TaskListener l = null;
        StepContext context = getContext();
        try {
            l = context.get(TaskListener.class);
        } catch (Exception x) {
            LOGGER.log(Level.WARNING, "Failed to find TaskListener in context");
        } finally {
            if (l == null) {
                l = new LogTaskListener(LOGGER, Level.FINE);
            }
        }
        return l.getLogger();
    }

    @Override
    protected String run() throws Exception {
        boolean returnLog = step.isReturnLog();
        String containerName = step.getName();
        int tailingLines = step.getTailingLines();
        int sinceSeconds = step.getSinceSeconds();
        int limitBytes = step.getLimitBytes();

        try {
            LOGGER.log(Level.FINE, "Starting containerLog step.");

            KubernetesNodeContext nodeContext = new KubernetesNodeContext(getContext());
            client = nodeContext.connectToCloud();

            String podName = nodeContext.getPodName();
            PodResource<Pod> pod = client.pods() //
                    .inNamespace(nodeContext.getNamespace()) //
                    .withName(podName);

            TimeTailPrettyLoggable<LogWatch> limited = limitBytes > 0
                    ? pod.inContainer(containerName).limitBytes(limitBytes)
                    : pod.inContainer(containerName);

            TailPrettyLoggable<LogWatch> since = sinceSeconds > 0 ? limited.sinceSeconds(sinceSeconds) : limited;

            PrettyLoggable<LogWatch> tailed = tailingLines > 0 ? since.tailingLines(tailingLines) : since;
            String log = tailed.getLog();

            if (returnLog) {
                return log;
            } else {
                logger().println("> start log of container '" + containerName + "' in pod '" + podName + "'");
                logger().print(log);
                if (log.length() > 0 && log.charAt(log.length() - 1) != '\n') {
                    logger().println();
                }
                logger().println("> end log of container '" + containerName + "' in pod '" + podName + "'");
            }

            return "";
        } catch (InterruptedException e) {
            logger().println("Interrupted while getting logs of container");
            LOGGER.log(Level.FINE, "interrupted while getting logs of container {1}", containerName);
            return "";
        } catch (Exception e) {
            String message = "Failed to get logs for container";
            logger().println(message);
            LOGGER.log(Level.WARNING, message, e);
            return "";
        }
    }

    @Override
    public void stop(Throwable cause) throws Exception {
        LOGGER.log(Level.FINE, "Stopping container log step.");
        super.stop(cause);
    }
}

@@ -735,52 +735,8 @@
 er;%0A
-import io.fabric8.kubernetes.api.model.Pod;%0A
 impo
@@ -839,117 +839,8 @@
 ch;%0A
-import io.fabric8.kubernetes.client.dsl.PodResource;%0Aimport io.fabric8.kubernetes.client.dsl.PrettyLoggable;%0A
 impo
@@ -2723,32 +2723,33 @@
 t.getPodName();%0A
+%0A
             PodR
@@ -2748,30 +2748,87 @@
     
-PodResource%3CPod%3E pod =
+TimeTailPrettyLoggable%3CLogWatch%3E limited = limitBytes %3E 0%0A                    ?
  cli
@@ -2837,24 +2837,32 @@
 t.pods() //%0A
+        
             
@@ -2933,16 +2933,24 @@
         
+   
+     
 .withNam
@@ -2963,66 +2963,47 @@
 ame)
-;%0A%0A            TimeTailPrettyLoggable%3CLogWatch%3E limited = 
+.inContainer(containerName).limitBytes(
 limi
@@ -3000,36 +3000,33 @@
 Bytes(limitBytes
- %3E 0
+)
 %0A               
@@ -3034,89 +3034,145 @@
     
-? pod.inContainer(containerName).limitBytes(limitBytes)%0A                    : pod
+: client.pods() //%0A                            .inNamespace(nodeContext.getNamespace()) //%0A                            .withName(podName)
 .inC
@@ -3328,42 +3328,22 @@
     
-PrettyLoggable%3CLogWatch%3E tailed
+String log
  = 
+(
 tail
@@ -3401,41 +3401,9 @@
 ince
-;%0A            String log = tailed
+)
 .get

Simplify imports