package com.commercetools.sdk.contrib;

import io.sphere.sdk.client.*;
import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.time.Duration;
import java.util.Properties;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeUnit;

public final class SphereClientRule extends ExternalResource implements BlockingSphereClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(SphereClientRule.class);
    private BlockingSphereClient client;

    @Override
    public void close() {
        LOGGER.warn("it is not recommended to close the client directly in " + getClass().getName());
        client.close();
    }

    @Override
    public <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest) {
        return client.execute(sphereRequest);
    }

    @Override
    public <T> T executeBlocking(final SphereRequest<T> sphereRequest) {
        return client.executeBlocking(sphereRequest);
    }

    @Override
    public <T> T executeBlocking(final SphereRequest<T> sphereRequest, final long l, final TimeUnit timeUnit) {
        return client.executeBlocking(sphereRequest, l, timeUnit);
    }

    @Override
    public <T> T executeBlocking(final SphereRequest<T> sphereRequest, final Duration duration) {
        return client.executeBlocking(sphereRequest, duration);
    }

    @Override
    protected void after() {
        client.close();
    }

    @Override
    protected void before() throws Throwable {
        final File file = findFile(new File("integrationtest.properties").getAbsoluteFile(), 5);
        try (final FileInputStream fileInputStream = new FileInputStream(file)) {
            final Properties properties = new Properties();
            properties.load(fileInputStream);
            final SphereClientConfig config =  SphereClientConfig.ofProperties(properties, "");
            final SphereClient underlying = SphereClientFactory.of().createClient(config);
            client = BlockingSphereClient.of(underlying, 20, TimeUnit.SECONDS);
        }
    }

    private static File findFile(final File initial, final int ttl) {
        if (ttl <= 0 || initial.exists()) {
            return initial;
        } else {
            final String name = initial.getName();
            final File parentFile = initial.getParentFile().getParentFile();
            final File newInitial = new File(parentFile, name).getAbsoluteFile();
            return findFile(newInitial, ttl - 1);
        }
    }
}

@@ -216,16 +216,44 @@
 Stream;%0A
+import java.io.IOException;%0A
 import j
@@ -1595,24 +1595,478 @@
 Throwable %7B%0A
+        if (System.getenv(%22JVM_SDK_CONTRIB_IT_PROJECT_KEY%22) != null) %7B%0A            initializeClientFromEnv();%0A        %7D else %7B%0A            initializeClientFromProperties();%0A        %7D%0A    %7D%0A%0A    private void initializeClientFromEnv() %7B%0A        final SphereClientConfig config = SphereClientConfig.ofEnvironmentVariables(%22JVM_SDK_CONTRIB_IT%22);%0A        initializeClient(config);%0A    %7D%0A%0A    private void initializeClientFromProperties() throws IOException %7B%0A
         fina
@@ -2383,17 +2383,16 @@
 config =
- 
  SphereC
@@ -2433,24 +2433,144 @@
 s, %22%22);%0A    
+        initializeClient(config);%0A        %7D%0A    %7D%0A%0A    private void initializeClient(final SphereClientConfig config) %7B%0A
         fina
@@ -2640,28 +2640,24 @@
 nt(config);%0A
-    
         clie
@@ -2720,26 +2720,16 @@
 CONDS);%0A
-        %7D%0A
     %7D%0A%0A 

allow test credentials via env args