/*
 * Licensed to Crate under one or more contributor license agreements.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.  Crate licenses this file
 * to you 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.
 *
 * However, if you have executed another commercial license agreement
 * with Crate these terms will supersede the license and you may use the
 * software solely pursuant to the terms of the relevant commercial
 * agreement.
 */

package io.crate.client;

import com.google.common.base.MoreObjects;
import com.google.common.base.Throwables;
import io.crate.action.sql.SQLBulkRequest;
import io.crate.action.sql.SQLBulkResponse;
import io.crate.action.sql.SQLRequest;
import io.crate.action.sql.SQLResponse;
import io.crate.testing.CrateTestCluster;
import io.crate.testing.CrateTestServer;
import org.elasticsearch.common.unit.TimeValue;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.TimeUnit;

public abstract class CrateClientIntegrationTest extends Assert {

    private static final String SQL_REQUEST_TIMEOUT_ENV = "CRATE_TESTS_SQL_REQUEST_TIMEOUT";
    protected static final TimeValue SQL_REQUEST_TIMEOUT = new TimeValue(Long.parseLong(
            MoreObjects.firstNonNull(System.getenv(SQL_REQUEST_TIMEOUT_ENV), "5")), TimeUnit.SECONDS);

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private static String tarBallPath;

    static {

        final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:crate-*.tar.gz");
        FileVisitor<Path> matcherVisitor = new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) {
                if (matcher.matches(file.getFileName())) {
                    tarBallPath = file.toAbsolutePath().toString();
                    return FileVisitResult.TERMINATE;
                }
                return FileVisitResult.CONTINUE;
            }
        };
        try {
            Files.walkFileTree(Paths.get(
                    System.getProperty("project_root") + "/app/build/distributions/"), matcherVisitor);
        } catch (IOException e) {
            Throwables.propagate(e);
        }
        assert tarBallPath != null;
    }

    protected CrateClient client;


    @ClassRule
    public static final CrateTestCluster testCluster = CrateTestCluster.fromFile(tarBallPath)
            .workingDir(Paths.get(System.getProperty("project_build_dir"), "crate-testing")).numberOfNodes(1).build();

    protected String serverAddress() {
        CrateTestServer server = testCluster.randomServer();
        return server.crateHost() + ':' + server.transportPort();
    }

    protected CrateClient client() {
        assert client != null : "client not set";
        return client;
    }

    private void waitForZeroCount(String stmt) {
        for (int i = 1; i < 10; i++) {
            SQLResponse r = client().sql(stmt).actionGet(5, TimeUnit.SECONDS);
            if (((Long) r.rows()[0][0]) == 0L) {
                return;
            }
            try {
                Thread.sleep(i * 100);
            } catch (InterruptedException e) {
                Throwables.propagate(e);
            }
        }
        throw new RuntimeException("waiting for zero result timed out");
    }

    protected void ensureYellow() {
        waitForZeroCount("select count(*) from sys.shards where \"primary\" = true and state <> 'STARTED'");
    }

    protected void ensureGreen() {
        waitForZeroCount("select count(*) from sys.shards where state <> 'STARTED'");
    }

    protected SQLResponse execute(String stmt) {
        return client().sql(stmt).actionGet(SQL_REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS);
    }

    protected SQLResponse execute(SQLRequest request) {
        return client().sql(request).actionGet(SQL_REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS);
    }

    protected SQLBulkResponse execute(String stmt, Object[][] bulkArgs) {
        return client().bulkSql(new SQLBulkRequest(stmt, bulkArgs)).actionGet(SQL_REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS);
    }
}

@@ -1568,17 +1568,21 @@
 io.file.
-*
+Files
 ;%0Aimport
@@ -1600,36 +1600,39 @@
 ile.
+P
 at
-tribute.BasicFileAttribute
+h;%0Aimport java.nio.file.Path
 s;%0Ai
@@ -2131,383 +2131,166 @@
 tic 
-String tarBallPath;%0A%0A    static %7B%0A%0A        final PathMatcher matcher = FileSystems.getDefault().getPathMatcher(%22glob:crate-*.tar.gz%22);%0A        FileVisitor%3CPath%3E matcherVisitor = new SimpleFileVisitor%3CPath%3E() %7B%0A            @Override%0A            public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) %7B%0A                if (matcher.matches(file.getFileName()))
+Path distributionsDir = Paths.get(System.getProperty(%22project_root%22) + %22/app/build/distributions%22);%0A%0A    private static String tarBallPath = null;%0A%0A    static
  %7B%0A 
@@ -2288,32 +2288,38 @@
 tatic %7B%0A        
+try %7B%0A
             tarB
@@ -2332,243 +2332,86 @@
 h = 
-file.toAbsolutePath().toString();%0A                    return FileVisitResult.TERMINATE;%0A                %7D%0A                return FileVisitResult.CONTINUE;%0A            %7D%0A        %7D;%0A        try %7B%0A            Files.walkFileTree(Paths.ge
+Files.newDirectoryStream(distributionsDir, %22crate-*.tar.gz%22).iterator().nex
 t(
+)
 %0A   
@@ -2427,93 +2427,35 @@
     
-    System.getProperty(%22project_root%22) + %22/app/build/distributions/%22), matcherVisitor
+.toAbsolutePath().toString(
 );%0A 

Use DirectoryStream to resolve crate tar file