/*
 *
 *  Copyright 2017 Netflix, Inc.
 *
 *     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.netflix.hollow.api.producer;

import com.netflix.hollow.api.producer.HollowProducer.Populator;
import com.netflix.hollow.api.producer.HollowProducer.WriteState;
import com.netflix.hollow.api.producer.fs.HollowFilesystemBlobStorageCleaner;
import com.netflix.hollow.api.producer.fs.HollowFilesystemPublisher;
import com.netflix.hollow.core.write.objectmapper.HollowPrimaryKey;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class HollowProducerBlobStorageCleanerTest {

    private static final String SCRATCH_DIR = System.getProperty("java.io.tmpdir");

    private File publishDir;

    @Before
    public void setUp() {
        publishDir = new File(SCRATCH_DIR, "publish-dir");
        publishDir.mkdir();
        for(File file : publishDir.listFiles()) {
            file.delete();
        }
    }

    @Test
    public void cleanSnapshotsWithDefaultValue() {
        HollowProducer.Publisher publisher = new HollowFilesystemPublisher(publishDir);
        HollowProducer.BlobStorageCleaner blobStorageCleaner = new HollowFilesystemBlobStorageCleaner(publishDir);
        HollowProducer producer = HollowProducer.withPublisher(publisher)
                                                .withBlobStorageCleaner(blobStorageCleaner)
                                                .withVersionMinter(new TestVersionMinter())
                                                .build();

        /// initialize the data -- classic producer creates the first state in the delta chain. 
        producer.runCycle(new Populator() {
            public void populate(WriteState state) throws Exception {
                state.add(new TypeA(1, "one", 1));
            }
        });

        HollowIncrementalProducer incrementalProducer = new HollowIncrementalProducer(producer);
        incrementalProducer.addOrModify(new TypeA(2, "two", 100));
        incrementalProducer.runCycle();
        incrementalProducer.addOrModify(new TypeA(3, "three", 1000));
        incrementalProducer.runCycle();
        incrementalProducer.addOrModify(new TypeA(4, "two", 100));
        incrementalProducer.runCycle();
        incrementalProducer.addOrModify(new TypeA(5, "three", 1000));
        incrementalProducer.runCycle();

        File[] files = listFiles(HollowProducer.Blob.Type.SNAPSHOT.prefix);
        List<String> fileNames = getFileNames(files);
        assert files.length == 5;

        incrementalProducer.addOrModify(new TypeA(6, "three", 1000));
        incrementalProducer.runCycle();
        incrementalProducer.addOrModify(new TypeA(7, "three", 1000));
        incrementalProducer.runCycle();

        File[] filesAfterCleanup = listFiles(HollowProducer.Blob.Type.SNAPSHOT.prefix);
        List<String> fileNamesAfterCleanup = getFileNames(filesAfterCleanup);

        Assert.assertEquals(5, files.length);
        Assert.assertEquals(Arrays.asList("snapshot-3", "snapshot-4", "snapshot-5", "snapshot-6", "snapshot-7"), fileNamesAfterCleanup);
        Assert.assertNotEquals(fileNamesAfterCleanup, fileNames);
    }

    @SuppressWarnings("unused")
    @HollowPrimaryKey(fields = { "id1", "id2" })
    private static class TypeA {
        int id1;
        String id2;
        long value;

        public TypeA(int id1, String id2, long value) {
            this.id1 = id1;
            this.id2 = id2;
            this.value = value;
        }
    }

    private File[] listFiles(final String blobType) {
        return publishDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.contains(blobType);
            }
        });
    }

    private List<String> getFileNames(File[] files) {
        List<String> fileNames = new ArrayList<>();
        for(File file : files) {
            fileNames.add(file.getName());
        }
        return fileNames;
    }

    @After
    public void removeAllFiles() {
        for(File file : publishDir.listFiles()) {
            file.delete();
        }
    }

    private static final class TestVersionMinter implements HollowProducer.VersionMinter  {
        private static AtomicInteger versionCounter = new AtomicInteger();

        @Override
        public long mint() {
            return versionCounter.incrementAndGet();
        }
    }
}

@@ -3690,145 +3690,8 @@
 h);%0A
-        Assert.assertEquals(Arrays.asList(%22snapshot-3%22, %22snapshot-4%22, %22snapshot-5%22, %22snapshot-6%22, %22snapshot-7%22), fileNamesAfterCleanup);%0A
     

fix order of assert parameters in test