// Path: src/main/java/org/echocat/gradle/plugins/golang/DependencyHandler.java
// public enum GetResult {
//     downloaded,
//     alreadyExists
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/model/GolangDependency.java
// public enum Type {
//     explicit,
//     implicit,
//     source,
//     system
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/DependencyHandler.java
// @Nonnull
// public static GetTask by(@Nonnull String configuration) {
//     return new GetTask(configuration);
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/model/Platform.java
// @Nonnull
// public static Platform currentPlatform() {
//     return CURRENT;
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/utils/Executor.java
// @Nonnull
// public static Executor executor(@Nonnull String executable) {
//     return executor(Paths.get(executable).toAbsolutePath());
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/utils/FileUtils.java
// public static void delete(@Nullable Path path) throws IOException {
//     if (path == null || !exists(path)) {
//         return;
//     }
//     if (isRegularFile(path)) {
//         doDelete(path);
//         return;
//     }
//     walkFileTree(path, new SimpleFileVisitor<Path>() {
//         @Override
//         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//             doDelete(file);
//             return CONTINUE;
//         }
// 
//         @Override
//         public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//             doDelete(dir);
//             return CONTINUE;
//         }
//     });
// }


import org.echocat.gradle.plugins.golang.DependencyHandler.GetResult;
import org.echocat.gradle.plugins.golang.model.*;
import org.echocat.gradle.plugins.golang.model.GolangDependency.Type;
import org.gradle.internal.logging.progress.ProgressLogger;
import javax.annotation.Nonnull;
import java.nio.file.Path;
import java.util.Map;
import java.util.Map.Entry;
import static java.lang.Boolean.TRUE;
import static java.nio.file.Files.exists;
import static org.echocat.gradle.plugins.golang.DependencyHandler.GetResult.downloaded;
import static org.echocat.gradle.plugins.golang.DependencyHandler.GetTask.by;
import static org.echocat.gradle.plugins.golang.model.Platform.currentPlatform;
import static org.echocat.gradle.plugins.golang.utils.Executor.executor;
import static org.echocat.gradle.plugins.golang.utils.FileUtils.delete;
import static org.gradle.api.internal.tasks.TaskExecutionOutcome.UP_TO_DATE;
    public void run() throws Exception {
        final ProgressLogger progress = startProgress("Get tools");

        final Map<GolangDependency, GetResult> dependencies = getDependencyHandler().get(by("tool"));
        boolean atLeastOneBuild = false;
        for (final Entry<GolangDependency, GetResult> entry : dependencies.entrySet()) {
            final GolangDependency dependency = entry.getKey();
            if (dependency.getType() == Type.explicit) {
                if (buildIfRequired(dependency, entry.getValue(), progress)) {
                    atLeastOneBuild = true;
                }
            }
        }
        if (!atLeastOneBuild) {
            getState().setOutcome(UP_TO_DATE);
        }

        progress.completed();
    }

    protected boolean buildIfRequired(@Nonnull GolangDependency dependency, @Nonnull GetResult getResult, @Nonnull ProgressLogger progress) throws Exception {
        final GolangSettings settings = getGolang();
        final BuildSettings build = getBuild();
        final ToolchainSettings toolchain = getToolchain();
        final Platform platform = currentPlatform();
        final Path targetBinaryFilename = targetBinaryFilename(dependency);

        if (getResult == downloaded || !exists(targetBinaryFilename)) {
            getLogger().info("Get tool {}...", dependency.getGroup());
            progress.progress("Get tool " + dependency.getGroup() + "...");
// Path: src/main/java/org/echocat/gradle/plugins/golang/DependencyHandler.java
// public enum GetResult {
//     downloaded,
//     alreadyExists
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/model/GolangDependency.java
// public enum Type {
//     explicit,
//     implicit,
//     source,
//     system
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/DependencyHandler.java
// @Nonnull
// public static GetTask by(@Nonnull String configuration) {
//     return new GetTask(configuration);
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/model/Platform.java
// @Nonnull
// public static Platform currentPlatform() {
//     return CURRENT;
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/utils/Executor.java
// @Nonnull
// public static Executor executor(@Nonnull String executable) {
//     return executor(Paths.get(executable).toAbsolutePath());
// }
// 
// Path: src/main/java/org/echocat/gradle/plugins/golang/utils/FileUtils.java
// public static void delete(@Nullable Path path) throws IOException {
//     if (path == null || !exists(path)) {
//         return;
//     }
//     if (isRegularFile(path)) {
//         doDelete(path);
//         return;
//     }
//     walkFileTree(path, new SimpleFileVisitor<Path>() {
//         @Override
//         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//             doDelete(file);
//             return CONTINUE;
//         }
// 
//         @Override
//         public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//             doDelete(dir);
//             return CONTINUE;
//         }
//     });
// }


// Path: src/main/java/org/echocat/gradle/plugins/golang/tasks/BaseGetTools.java
import org.echocat.gradle.plugins.golang.DependencyHandler.GetResult;
import org.echocat.gradle.plugins.golang.model.*;
import org.echocat.gradle.plugins.golang.model.GolangDependency.Type;
import org.gradle.internal.logging.progress.ProgressLogger;
import javax.annotation.Nonnull;
import java.nio.file.Path;
import java.util.Map;
import java.util.Map.Entry;
import static java.lang.Boolean.TRUE;
import static java.nio.file.Files.exists;
import static org.echocat.gradle.plugins.golang.DependencyHandler.GetResult.downloaded;
import static org.echocat.gradle.plugins.golang.DependencyHandler.GetTask.by;
import static org.echocat.gradle.plugins.golang.model.Platform.currentPlatform;
import static org.echocat.gradle.plugins.golang.utils.Executor.executor;
import static org.echocat.gradle.plugins.golang.utils.FileUtils.delete;
import static org.gradle.api.internal.tasks.TaskExecutionOutcome.UP_TO_DATE;

    public void run() throws Exception {
        final ProgressLogger progress = startProgress("Get tools");

        final Map<GolangDependency, GetResult> dependencies = getDependencyHandler().get(by("tool"));
        boolean atLeastOneBuild = false;
        for (final Entry<GolangDependency, GetResult> entry : dependencies.entrySet()) {
            final GolangDependency dependency = entry.getKey();
            if (dependency.getType() == Type.explicit) {
                if (buildIfRequired(dependency, entry.getValue(), progress)) {
                    atLeastOneBuild = true;
                }
            }
        }
        if (!atLeastOneBuild) {
            getState().setOutcome(UP_TO_DATE);
        }

        progress.completed();
    }

    protected boolean buildIfRequired(@Nonnull GolangDependency dependency, @Nonnull GetResult getResult, @Nonnull ProgressLogger progress) throws Exception {
        final GolangSettings settings = getGolang();
        final BuildSettings build = getBuild();
        final ToolchainSettings toolchain = getToolchain();
        final Platform platform = currentPlatform();
        final Path targetBinaryFilename = targetBinaryFilename(dependency);

        if (getResult == downloaded || !exists(targetBinaryFilename)) {
            getLogger().info("Get tool {}...", dependency.getGroup());
            progress.progress("Get tool " + dependency.getGroup() + "...");
            delete(targetBinaryFilename.getParent());