/*
 * Copyright 2018 the original author or authors.
 *
 * 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 org.gradle.cache.internal;

import com.google.common.collect.Sets;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.gradle.util.GradleVersion;

import javax.annotation.Nullable;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.SortedSet;

import static org.apache.commons.io.filefilter.FileFilterUtils.directoryFileFilter;

public class VersionSpecificCacheDirectoryScanner {

    private final File baseDir;

    public VersionSpecificCacheDirectoryScanner(File baseDir) {
        this.baseDir = baseDir;
    }

    public File getBaseDir() {
        return baseDir;
    }

    public File getDirectory(GradleVersion gradleVersion) {
        return new File(baseDir, gradleVersion.getVersion());
    }

    public SortedSet<VersionSpecificCacheDirectory> getExistingDirectories() {
        SortedSet<VersionSpecificCacheDirectory> result = Sets.newTreeSet();
        for (File subDir : listVersionSpecificCacheDirs()) {
            GradleVersion version = tryParseGradleVersion(subDir);
            if (version != null) {
                result.add(new VersionSpecificCacheDirectory(subDir, version));
            }
        }
        return result;
    }

    private Collection<File> listVersionSpecificCacheDirs() {
        FileFilter combinedFilter = FileFilterUtils.and(directoryFileFilter(), new RegexFileFilter("^\\d.*"));
        File[] result = baseDir.listFiles(combinedFilter);
        return result == null ? Collections.<File>emptySet() : Arrays.asList(result);
    }

    @Nullable
    private GradleVersion tryParseGradleVersion(File dir) {
        try {
            return GradleVersion.version(dir.getName());
        } catch (Exception e) {
            return null;
        }
    }
}

@@ -821,62 +821,60 @@
 dle.
-util.GradleVersion;%0A%0Aimport javax.annotation.Nullable;
+internal.Try;%0Aimport org.gradle.util.GradleVersion;%0A
 %0Aimp
@@ -1029,16 +1029,90 @@
 rtedSet;
+%0Aimport java.util.concurrent.Callable;%0Aimport java.util.function.Consumer;
 %0A%0Aimport
@@ -1657,16 +1657,22 @@
         
+final 
 SortedSe
@@ -1745,16 +1745,22 @@
    for (
+final 
 File sub
@@ -1811,16 +1811,20 @@
         
+Try%3C
 GradleVe
@@ -1828,16 +1828,17 @@
 eVersion
+%3E
  version
@@ -1887,31 +1887,157 @@
     
-if (version != null) %7B%0A
+version.ifSuccessful(new Consumer%3CGradleVersion%3E() %7B%0A                @Override%0A                public void accept(GradleVersion gradleVersion) %7B%0A    
     
@@ -2101,17 +2101,23 @@
 subDir, 
-v
+gradleV
 ersion))
@@ -2122,33 +2122,53 @@
 ));%0A            
-%7D
+    %7D%0A            %7D);
 %0A        %7D%0A     
@@ -2521,22 +2521,8 @@
  %7D%0A%0A
-    @Nullable%0A
     
@@ -2529,16 +2529,20 @@
 private 
+Try%3C
 GradleVe
@@ -2546,16 +2546,17 @@
 eVersion
+%3E
  tryPars
@@ -2570,16 +2570,22 @@
 Version(
+final 
 File dir
@@ -2600,137 +2600,212 @@
     
-try %7B%0A            return GradleVersion.version(dir.getName());%0A        %7D catch (Exception e) %7B%0A            return null;%0A        %7D
+return Try.ofFailable(new Callable%3CGradleVersion%3E() %7B%0A            @Override%0A            public GradleVersion call() %7B%0A                return GradleVersion.version(dir.getName());%0A            %7D%0A        %7D);
 %0A   

Use Try in VersionSpecificCacheDirectoryScanner