/*
 * Copyright 2016 Palantir Technologies, Inc. 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 com.palantir.docker.compose;

import com.palantir.docker.compose.connection.Container;
import com.palantir.docker.compose.connection.ContainerCache;
import com.palantir.docker.compose.connection.waiting.MultiServiceHealthCheck;
import com.palantir.docker.compose.connection.waiting.ServiceWait;
import com.palantir.docker.compose.connection.waiting.SingleServiceHealthCheck;
import com.palantir.docker.compose.execution.DockerCompose;
import com.palantir.docker.compose.logging.DoNothingLogCollector;
import com.palantir.docker.compose.logging.FileLogCollector;
import com.palantir.docker.compose.logging.LogCollector;
import org.joda.time.Duration;

import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;
import static org.joda.time.Duration.standardMinutes;

public class DockerCompositionBuilder {
    private static final Duration DEFAULT_TIMEOUT = standardMinutes(2);

    private final List<ServiceWait> serviceWaits = new ArrayList<>();
    private final DockerCompose dockerComposeProcess;
    private final ContainerCache containers;
    private LogCollector logCollector = new DoNothingLogCollector();

    public DockerCompositionBuilder(DockerCompose dockerComposeProcess) {
        this.dockerComposeProcess = dockerComposeProcess;
        this.containers = new ContainerCache(dockerComposeProcess);
    }

    public DockerCompositionBuilder waitingForService(String serviceName, SingleServiceHealthCheck check) {
        return waitingForService(serviceName, check, DEFAULT_TIMEOUT);
    }

    public DockerCompositionBuilder waitingForServices(List<String> services, MultiServiceHealthCheck check) {
        return waitingForServices(services, check, DEFAULT_TIMEOUT);
    }

    public DockerCompositionBuilder waitingForServices(List<String> services, MultiServiceHealthCheck check, Duration timeout) {
        List<Container> containersToWaitFor = services.stream()
                .map(containers::get)
                .collect(toList());
        serviceWaits.add(new ServiceWait(containersToWaitFor, check, timeout));
        return this;
    }

    public DockerCompositionBuilder waitingForService(String serviceName, SingleServiceHealthCheck check, Duration timeout) {
        serviceWaits.add(new ServiceWait(containers.get(serviceName), check, timeout));
        return this;
    }

    public DockerCompositionBuilder saveLogsTo(String path) {
        this.logCollector = FileLogCollector.fromPath(path);
        return this;
    }

    public DockerComposition build() {
        return new DockerComposition(dockerComposeProcess, serviceWaits, logCollector, containers);
    }
}

@@ -1068,16 +1068,84 @@
 ompose;%0A
+import com.palantir.docker.compose.execution.RetryingDockerCompose;%0A
 import c
@@ -1733,31 +1733,24 @@
 ockerCompose
-Process
 ;%0A    privat
@@ -1852,16 +1852,51 @@
 ector();
+%0A    private int retryAttempts = 3;
 %0A%0A    pu
@@ -1952,23 +1952,16 @@
 rCompose
-Process
 ) %7B%0A    
@@ -1982,23 +1982,16 @@
 rCompose
-Process
  = docke
@@ -1998,23 +1998,16 @@
 rCompose
-Process
 ;%0A      
@@ -2058,23 +2058,16 @@
 rCompose
-Process
 );%0A    %7D
@@ -3241,76 +3241,323 @@
 tion
- b
+B
 uild
-() %7B%0A        return new DockerComposition(dockerComposeProcess
+er retryAttempts(int retryAttempts) %7B%0A        this.retryAttempts = retryAttempts;%0A        return this;%0A    %7D%0A%0A    public DockerComposition build() %7B%0A        DockerCompose retryingDockerCompose = new RetryingDockerCompose(retryAttempts, dockerCompose);%0A        return new DockerComposition(retryingDockerCompose
 , se

Add retry attempts to DockerCompositionBuilder