package com.uber.okbuck.core.task;

import com.google.common.collect.Sets;
import com.uber.okbuck.OkBuckGradlePlugin;
import com.uber.okbuck.core.model.base.ProjectType;
import com.uber.okbuck.core.util.ProjectUtil;

import org.apache.commons.io.FileUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * A task to cleanup stale BUCK files
 */
@SuppressWarnings({"WeakerAccess", "CanBeFinal", "unused", "ResultOfMethodCallIgnored", "NewApi"})
public class OkBuckCleanTask extends DefaultTask {

    @Input
    public Set<Project> projects = new HashSet<>();

    @TaskAction
    void clean() throws IOException {
        Project rootProject = getProject();
        Path rootProjectPath = rootProject.getProjectDir().toPath();

        File okbuckState = rootProject.file(OkBuckGradlePlugin.OKBUCK_STATE);

        // Get last project paths
        Set<String> lastProjectPaths;
        if (okbuckState.exists()) {
            lastProjectPaths = Files.lines(okbuckState.toPath())
                    .map(String::trim)
                    .filter(s -> s != null && s.length() > 0)
                    .collect(Collectors.toSet());
        } else {
            lastProjectPaths = new HashSet<>();
            okbuckState.getParentFile().mkdirs();
            okbuckState.createNewFile();
        }

        // Get current project relative paths
        Set<String> currentProjectPaths =
                projects.stream()
                        .filter(project -> ProjectUtil.getType(project) != ProjectType.UNKNOWN)
                        .map(project -> rootProjectPath
                                .relativize(project.getProjectDir().toPath()).toString()
                        )
                        .collect(Collectors.toSet());

        Sets.SetView<String> difference = Sets.difference(lastProjectPaths, currentProjectPaths);

        // Delete stale project's BUCK file
        difference
                .parallelStream()
                .map(p -> rootProjectPath.resolve(p).resolve(OkBuckGradlePlugin.BUCK))
                .forEach(OkBuckCleanTask::deleteQuietly);

        // Delete gen folders
        difference
                .parallelStream()
                .map(p -> rootProjectPath.resolve(OkBuckGradlePlugin.OKBUCK_GEN).resolve(p))
                .forEach(OkBuckCleanTask::deleteQuietly);

        // Save generated project's BUCK file path
        Files.write(
                okbuckState.toPath(),
                currentProjectPaths
                        .stream()
                        .sorted()
                        .collect(Collectors.toList())
        );
    }

    private static void deleteQuietly(Path p) {
        File f = p.toFile();
        if (!f.exists()) {
            return;
        }
        try {
            if (f.isDirectory()) {
                FileUtils.deleteDirectory(f);
            } else {
                Files.delete(p);
            }
        } catch (IOException ignored) {}
    }
}

@@ -214,48 +214,8 @@
 l;%0A%0A
-import org.apache.commons.io.FileUtils;%0A
 impo
@@ -430,36 +430,166 @@
 File
-s;%0Aimport java.nio.file.Path
+VisitResult;%0Aimport java.nio.file.Files;%0Aimport java.nio.file.Path;%0Aimport java.nio.file.SimpleFileVisitor;%0Aimport java.nio.file.attribute.BasicFileAttributes
 ;%0Aim
@@ -3037,84 +3037,322 @@
     
-File f = p.toFile();%0A        if (!f.exists()) %7B%0A            return;%0A
+try %7B%0A            Files.walkFileTree(p, new SimpleFileVisitor%3CPath%3E() %7B%0A                @Override%0A                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException %7B%0A                    Files.delete(file);%0A                    return FileVisitResult.CONTINUE;%0A       
         
 %7D%0A  
@@ -3347,26 +3347,33 @@
         
+ 
 %7D%0A
+%0A     
         
 try %7B%0A  
@@ -3356,37 +3356,44 @@
 %7D%0A%0A             
-try %7B
+   @Override
 %0A            if 
@@ -3393,31 +3393,106 @@
     
-if (f.isDirectory()) %7B%0A
+    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException %7B%0A    
     
@@ -3511,20 +3511,16 @@
 File
-Util
 s.delete
 Dire
@@ -3519,19 +3519,12 @@
 lete
-Directory(f
+(dir
 );%0A 
@@ -3530,32 +3530,64 @@
             
-%7D else %7B
+        return FileVisitResult.CONTINUE;
 %0A           
@@ -3595,24 +3595,9 @@
     
-Files.delete(p);
+%7D
 %0A   
@@ -3598,32 +3598,34 @@
  %7D%0A            %7D
+);
 %0A        %7D catch

Simplify cleanup logic in okbuckclean