package de.hftstuttgart.utils;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class DockerUtil {
    private static final Logger LOG = LogManager.getLogger(DockerUtil.class);

    private DockerClient dockerClient;

    public DockerUtil(Environment env) {
        LOG.info("initializing Docker tools");
        LOG.debug("create docker client config");
        DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder().build();

        LOG.debug("create docker http client");
        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
            .dockerHost(dockerClientConfig.getDockerHost())
            .sslConfig(dockerClientConfig.getSSLConfig())
            .build();

        LOG.debug("create docker client");
        dockerClient = DockerClientImpl.getInstance(dockerClientConfig, httpClient);
    }

    public int runContainer(String image, Bind... binds) throws InterruptedException, IOException
    {
        LOG.debug(String.format("pull image: %s", image));
        dockerClient.pullImageCmd(image)
            .start()
            .awaitCompletion()
            .close();

        LOG.debug("creating container");
        CreateContainerResponse containerResponse = dockerClient.createContainerCmd("testcontainer")
            .withImage(image)
            .withHostConfig(
                HostConfig.newHostConfig()
                    .withBinds(binds))
            .exec();
        LOG.debug(String.format("container created: %s", containerResponse.getId()));

        LOG.debug(String.format("starting container %s", containerResponse.getId()));
        dockerClient.startContainerCmd(containerResponse.getId()).exec();

        LOG.debug(String.format("waiting for completion of container %s", containerResponse.getId()));
        int ret = dockerClient
            .waitContainerCmd(containerResponse.getId())
            .start()
            .awaitCompletion()
            .awaitStatusCode();
        LOG.debug(String.format("container completed with status %d", ret));

        LOG.debug(String.format("deleting container %s", containerResponse.getId()));
        dockerClient.removeContainerCmd(containerResponse.getId())
            .withRemoveVolumes(true)
            .exec();

        return ret;
    }
}
