package org.metaborg.spoofax.core.resource;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;

import org.apache.commons.vfs2.AllFileSelector;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.provider.local.LocalFile;
import org.apache.commons.vfs2.provider.res.ResourceFileSystemConfigBuilder;
import org.metaborg.spoofax.core.SpoofaxModule;
import org.metaborg.spoofax.core.SpoofaxRuntimeException;

import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.name.Named;

public class ResourceService implements IResourceService {
    private final FileSystemManager fileSystemManager;
    private final FileSystemOptions fileSystemOptions;

    private static IResourceService resourceService;
    public static void writeFileObject(FileObject fo, ObjectOutput out) throws IOException {
    	out.writeObject(fo.getName().getURI());
    }
    public static FileObject readFileObject(ObjectInput in) throws ClassNotFoundException, IOException {
    	if (resourceService == null)
    		resourceService = Guice.createInjector(new SpoofaxModule()).getInstance(IResourceService.class);
    	
    	String uri = (String) in.readObject();
    	return resourceService.resolve(uri);
    }

    @Inject public ResourceService(FileSystemManager fileSystemManager,
        @Named("ResourceClassLoader") ClassLoader classLoader) {
        this.fileSystemManager = fileSystemManager;
        this.fileSystemOptions = new FileSystemOptions();

        if(classLoader == null)
            classLoader = this.getClass().getClassLoader();
        ResourceFileSystemConfigBuilder.getInstance().setClassLoader(fileSystemOptions, classLoader);
    }


    @Override public FileObject root() {
        try {
            return fileSystemManager.getBaseFile();
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public FileObject resolve(String uri) {
        try {
            return fileSystemManager.resolveFile(uri, fileSystemOptions);
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public FileObject resolve(File file) {
        try {
            return fileSystemManager.toFileObject(file);
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public Iterable<FileObject> resolveAll(Iterable<String> uris) {
        final Collection<FileObject> files = Lists.newLinkedList();
        for(String uri : uris) {
            files.add(resolve(uri));
        }
        return files;
    }

    @Override public FileName resolveURI(String uri) {
        try {
            return fileSystemManager.resolveURI(uri);
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public File localFile(FileObject resource) {
        try {
            return resource.getFileSystem().replicateFile(resource, new AllFileSelector());
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public File localPath(FileObject resource) {
        if(resource instanceof LocalFile) {
            return new File(resource.getName().getPath());
        }
        return null;
    }


    @Override public FileObject userStorage() {
        try {
            final FileObject storageDir = root().resolveFile(".cache");
            storageDir.createFolder();
            return storageDir;
        } catch(FileSystemException e) {
            throw new SpoofaxRuntimeException(e);
        }
    }

    @Override public FileSystemManager manager() {
        return fileSystemManager;
    }
}

@@ -458,16 +458,52 @@
 ptions;%0A
+import org.apache.commons.vfs2.VFS;%0A
 import o
@@ -547,24 +547,24 @@
 .LocalFile;%0A
-
 import org.a
@@ -632,56 +632,8 @@
 er;%0A
-import org.metaborg.spoofax.core.SpoofaxModule;%0A
 impo
@@ -731,40 +731,8 @@
 ts;%0A
-import com.google.inject.Guice;%0A
 impo
@@ -972,61 +972,8 @@
 s;%0A%0A
-    private static IResourceService resourceService;%0A
     
@@ -1221,151 +1221,8 @@
 n %7B%0A
-    %09if (resourceService == null)%0A    %09%09resourceService = Guice.createInjector(new SpoofaxModule()).getInstance(IResourceService.class);%0A    %09%0A
     
@@ -1277,31 +1277,32 @@
 urn 
-resourceService
+VFS.getManager()
 .resolve
 (uri
@@ -1293,24 +1293,28 @@
 er().resolve
+File
 (uri);%0A    %7D

use plain VFS manager to serialize file objects