/*
 * Copyright 2013 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at http://www.eclipse.org/legal/epl-v10.html
 */
package io.liveoak.filesystem;

import io.liveoak.spi.RequestContext;
import io.liveoak.spi.resource.async.Resource;
import io.liveoak.spi.resource.async.ResourceSink;
import io.liveoak.spi.resource.async.Responder;
import org.vertx.java.core.Vertx;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Bob McWhirter
 */
public class DirectoryResource implements FSResource {

    public DirectoryResource(DirectoryResource parent, File file) {
        this.parent = parent;
        this.file = file;
    }

    public Vertx vertx() {
        return this.parent.vertx();
    }

    public File file() {
        return this.file;
    }

    @Override
    public void readMembers(RequestContext ctx, ResourceSink sink) {
        vertx().fileSystem().readDir(this.file.getPath(), (result) -> {
            if (result.failed()) {
                sink.close();
            } else {
                List<File> sorted = new ArrayList<>();

                for (String filename : result.result()) {
                    File child = new File(filename);
                    sorted.add( child );
                }

                sorted.sort((left, right) -> {
                    if ( left.isDirectory() && right.isDirectory()) {
                        return 0;
                    }

                    if ( left.isFile() && right.isFile() ) {
                        return 0;
                    }

                    if ( left.isDirectory() ) {
                        return -1;
                    }

                    if ( left.isFile() ) {
                        return 1;
                    }

                    return 0;

                });

                for ( File each : sorted ) {
                    if ( each.isDirectory() ) {
                        sink.accept( createDirectoryResource( this, each ));
                    } else {
                        sink.accept( createFileResource( this, each ));
                    }
                }
                sink.close();
            }
        });
    }

    @Override
    public Resource parent() {
        return this.parent;
    }

    @Override
    public String id() {
        return this.file.getName();
    }

    @Override
    public void readMember(RequestContext ctx, String id, Responder responder) {
        File path = new File(this.file, id);
        vertx().fileSystem().exists(path.getPath(), (existResult) -> {
            if (existResult.succeeded() && existResult.result()) {
                if (path.isDirectory()) {
                    responder.resourceRead(createDirectoryResource(this, path));
                } else {
                    responder.resourceRead(createFileResource(this, path));
                }
            } else {
                responder.noSuchResource(id);
            }
        });
    }

    protected DirectoryResource createDirectoryResource(DirectoryResource parent, File path) {
        return new DirectoryResource(parent, path);
    }

    protected FileResource createFileResource(DirectoryResource parent, File file) {
        return new FileResource(parent, file);
    }

    public String toString() {
        return "[DirectoryResource: file=" + this.file.getAbsolutePath() + "]";
    }

    private DirectoryResource parent;
    protected File file;
}

@@ -2007,38 +2007,32 @@
 rectoryResource(
- this,
  each ));%0A      
@@ -2114,14 +2114,8 @@
 rce(
- this,
  eac
@@ -2764,38 +2764,32 @@
 rectoryResource(
-this, 
 path));%0A        
@@ -2871,14 +2871,8 @@
 rce(
-this, 
 path
@@ -3053,34 +3053,8 @@
 rce(
-DirectoryResource parent, 
 File
@@ -3099,22 +3099,20 @@
 esource(
-parent
+this
 , path);
@@ -3169,34 +3169,8 @@
 rce(
-DirectoryResource parent, 
 File
@@ -3210,22 +3210,20 @@
 esource(
-parent
+this
 , file);

Modify filesystem factory methods to use this, instead of having it passed in