/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch 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.
 */
package org.elasticsearch.snapshots;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.repositories.RepositoriesService;
import org.elasticsearch.repositories.RepositoryMissingException;
import org.elasticsearch.snapshots.mockstore.MockRepository;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Ignore;

import java.io.File;

import static org.hamcrest.Matchers.equalTo;

/**
 */
@Ignore
public abstract class AbstractSnapshotTests extends ElasticsearchIntegrationTest {

    public static long getFailureCount(String repository) {
        long failureCount = 0;
        for (RepositoriesService repositoriesService : cluster().getInstances(RepositoriesService.class)) {
            MockRepository mockRepository = (MockRepository) repositoriesService.repository(repository);
            failureCount += mockRepository.getFailureCount();
        }
        return failureCount;
    }

    public static int numberOfFiles(File dir) {
        int count = 0;
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    count += numberOfFiles(file);
                } else {
                    count++;
                }
            }
        }
        return count;
    }

    public static void stopNode(final String node) {
        cluster().stopRandomNode(new Predicate<Settings>() {
            @Override
            public boolean apply(Settings settings) {
                return settings.get("name").equals(node);
            }
        });
    }

    public void waitForBlock(String node, String repository, TimeValue timeout) throws InterruptedException {
        long start = System.currentTimeMillis();
        RepositoriesService repositoriesService = cluster().getInstance(RepositoriesService.class, node);
        MockRepository mockRepository = (MockRepository) repositoriesService.repository(repository);
        while (System.currentTimeMillis() - start < timeout.millis()) {
            if (mockRepository.blocked()) {
                return;
            }
            Thread.sleep(100);
        }
        fail("Timeout!!!");
    }

    public SnapshotInfo waitForCompletion(String repository, String snapshot, TimeValue timeout) throws InterruptedException {
        long start = System.currentTimeMillis();
        while (System.currentTimeMillis() - start < timeout.millis()) {
            ImmutableList<SnapshotInfo> snapshotInfos = client().admin().cluster().prepareGetSnapshots(repository).setSnapshots(snapshot).get().getSnapshots();
            assertThat(snapshotInfos.size(), equalTo(1));
            if (snapshotInfos.get(0).state().completed()) {
                return snapshotInfos.get(0);
            }
            Thread.sleep(100);
        }
        fail("Timeout!!!");
        return null;
    }

    public static String blockNodeWithIndex(String index) {
        for(String node : cluster().nodesInclude("test-idx")) {
            ((MockRepository)cluster().getInstance(RepositoriesService.class, node).repository("test-repo")).blockOnDataFiles(true);
            return node;
        }
        fail("No nodes for the index " + index + " found");
        return null;
    }

    public static void unblockNode(String node) {
        ((MockRepository)cluster().getInstance(RepositoriesService.class, node).repository("test-repo")).unblock();
    }
}

@@ -905,24 +905,212 @@
 utableList;%0A
+import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;%0Aimport org.elasticsearch.cluster.metadata.SnapshotId;%0Aimport org.elasticsearch.cluster.metadata.SnapshotMetaData;%0A
 import org.e
@@ -1259,74 +1259,8 @@
 ce;%0A
-import org.elasticsearch.repositories.RepositoryMissingException;%0A
 impo
@@ -3422,32 +3422,102 @@
 ntTimeMillis();%0A
+        SnapshotId snapshotId = new SnapshotId(repository, snapshot);%0A
         while (S
@@ -3564,32 +3564,32 @@
 out.millis()) %7B%0A
-
             Immu
@@ -3842,32 +3842,433 @@
 .completed()) %7B%0A
+                // Make sure that snapshot clean up operations are finished%0A                ClusterStateResponse stateResponse = client().admin().cluster().prepareState().get();%0A                SnapshotMetaData snapshotMetaData = stateResponse.getState().getMetaData().custom(SnapshotMetaData.TYPE);%0A                if (snapshotMetaData == null %7C%7C snapshotMetaData.snapshot(snapshotId) == null) %7B%0A    
                 
@@ -4292,24 +4292,42 @@
 fos.get(0);%0A
+                %7D%0A
             

Make sure that a snapshot is completed before trying to modify repository