/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.apache.cordova.file;

import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URLDecoder;
import java.util.ArrayList;

/**
 * This class provides SD card file and directory services to JavaScript.
 * Only files on the SD card can be accessed.
 */
public class FileUtils extends CordovaPlugin {
    private static final String LOG_TAG = "FileUtils";

    public static int NOT_FOUND_ERR = 1;
    public static int SECURITY_ERR = 2;
    public static int ABORT_ERR = 3;

    public static int NOT_READABLE_ERR = 4;
    public static int ENCODING_ERR = 5;
    public static int NO_MODIFICATION_ALLOWED_ERR = 6;
    public static int INVALID_STATE_ERR = 7;
    public static int SYNTAX_ERR = 8;
    public static int INVALID_MODIFICATION_ERR = 9;
    public static int QUOTA_EXCEEDED_ERR = 10;
    public static int TYPE_MISMATCH_ERR = 11;
    public static int PATH_EXISTS_ERR = 12;

    public static int TEMPORARY = 0;
    public static int PERSISTENT = 1;
    public static int RESOURCE = 2;
    public static int APPLICATION = 3;
    
    // This field exists only to support getEntry, below, which has been deprecated
    private static FileUtils filePlugin;

    private interface FileOp {
        void run(  ) throws Exception;
    }
    
    private ArrayList<Filesystem> filesystems;

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
    	super.initialize(cordova, webView);
    	this.filesystems = new ArrayList<Filesystem>();
    	
    	File fp;
    	String tempRoot;
    	String persistentRoot;
    	if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    		persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
    		tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() +
    				"/Android/data/" + cordova.getActivity().getPackageName() + "/cache/";
    	} else {
    		persistentRoot = "/data/data/" + cordova.getActivity().getPackageName();
    		tempRoot = "/data/data/" + cordova.getActivity().getPackageName() + "/cache/";
    	}
    	// Create the cache dir if it doesn't exist.
    	fp = new File(tempRoot);
    	fp.mkdirs();
    	this.filesystems.add(new LocalFilesystem(cordova, "temporary", tempRoot));
    	this.filesystems.add(new LocalFilesystem(cordova, "persistent", persistentRoot));
    	this.filesystems.add(new ContentFilesystem(cordova));

    	// Initialize static plugin reference for deprecated getEntry method
    	if (filePlugin == null) {
    		filePlugin = this;
    	}
    }
    
    public Filesystem filesystemForURL(LocalFilesystemURL localURL) {
    	try {
    		return this.filesystems.get(localURL.filesystemType);
    	} catch (ArrayIndexOutOfBoundsException e) {
    		return null;
    	}
    }
    
    @Override
    public Uri remapUri(Uri uri) {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(uri);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		return null;
        	}
        	return Uri.parse("file:///" + fs.filesystemPathForURL(inputURL));
        } catch (IllegalArgumentException e) {
        	return null;
        }
    }

    /**
     * Executes the request and returns whether the action was valid.
     *
     * @param action 		The action to execute.
     * @param args 		JSONArray of arguments for the plugin.
     * @param callbackContext	The callback context used when calling back into JavaScript.
     * @return 			True if the action was valid, false otherwise.
     */
    public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if (action.equals("testSaveLocationExists")) {
            threadhelper( new FileOp( ){
                public void run() {
                    boolean b = DirectoryManager.testSaveLocationExists();
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                }
            },callbackContext);
        }
        else if (action.equals("getFreeDiskSpace")) {
            threadhelper( new FileOp( ){
                public void run() {
                    long l = DirectoryManager.getFreeDiskSpace(false);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l));
                }
            },callbackContext);
        }
        else if (action.equals("testFileExists")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() {
                    boolean b = DirectoryManager.testFileExists(fname);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                }
            }, callbackContext);
        }
        else if (action.equals("testDirectoryExists")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() {
                    boolean b = DirectoryManager.testFileExists(fname);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                }
            }, callbackContext);
        }
        else if (action.equals("readAsText")) {
            final String encoding = args.getString(1);
            final int start = args.getInt(2);
            final int end = args.getInt(3);
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws MalformedURLException {
                    readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING);
                }
            }, callbackContext);
        }
        else if (action.equals("readAsDataURL")) {
            final int start = args.getInt(1);
            final int end = args.getInt(2);
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws MalformedURLException  {
                    readFileAs(fname, start, end, callbackContext, null, -1);
                }
            }, callbackContext);
        }
        else if (action.equals("readAsArrayBuffer")) {
            final int start = args.getInt(1);
            final int end = args.getInt(2);
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws MalformedURLException  {
                    readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER);
                }
            },callbackContext);
        }
        else if (action.equals("readAsBinaryString")) {
            final int start = args.getInt(1);
            final int end = args.getInt(2);
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws MalformedURLException  {
                    readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING);
                }
            }, callbackContext);
        }
        else if (action.equals("write")) {
            final String fname=args.getString(0);
            final String data=args.getString(1);
            final int offset=args.getInt(2);
            final Boolean isBinary=args.getBoolean(3);
            threadhelper( new FileOp( ){
                public void run() throws FileNotFoundException, IOException, NoModificationAllowedException {
                    long fileSize = write(fname, data, offset, isBinary);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
                }
            }, callbackContext);
        }
        else if (action.equals("truncate")) {
            final String fname=args.getString(0);
            final int offset=args.getInt(1);
            threadhelper( new FileOp( ){
                public void run( ) throws FileNotFoundException, IOException, NoModificationAllowedException {
                    long fileSize = truncateFile(fname, offset);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
                }
            }, callbackContext);
        }
        else if (action.equals("requestFileSystem")) {
            final int fstype=args.getInt(0);
            final long size = args.optLong(1);
            threadhelper( new FileOp( ){
                public void run() throws IOException, JSONException {
                    if (size != 0 && size > (DirectoryManager.getFreeDiskSpace(true) * 1024)) {
                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR));
                    } else {
                        JSONObject obj = requestFileSystem(fstype);
                        callbackContext.success(obj);
                    }
                }
            }, callbackContext);
        }
        else if (action.equals("resolveLocalFileSystemURI")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws IOException, JSONException {
                    JSONObject obj = resolveLocalFileSystemURI(fname);
                    callbackContext.success(obj);
                }
            },callbackContext);
        }
        else if (action.equals("getMetadata")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws FileNotFoundException, JSONException, MalformedURLException {
                    JSONObject obj = getFileMetadata(fname);
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, obj.getLong("lastModifiedDate")));
                }
            }, callbackContext);
        }
        else if (action.equals("getFileMetadata")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws FileNotFoundException, JSONException, MalformedURLException {
                    JSONObject obj = getFileMetadata(fname);
                    callbackContext.success(obj);
                }
            },callbackContext);
        }
        else if (action.equals("getParent")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws JSONException, IOException {
                    JSONObject obj = getParent(fname);
                    callbackContext.success(obj);
                }
            },callbackContext);
        }
        else if (action.equals("getDirectory")) {
            final String dirname=args.getString(0);
            final String fname=args.getString(1);
            threadhelper( new FileOp( ){
                public void run() throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                   JSONObject obj = getFile(dirname, fname, args.optJSONObject(2), true);
                   callbackContext.success(obj);
                }
            },callbackContext);
        }
        else if (action.equals("getFile")) {
            final String dirname=args.getString(0);
            final String fname=args.getString(1);
            threadhelper( new FileOp( ){
                public void run() throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                    JSONObject obj = getFile(dirname, fname, args.optJSONObject(2), false);
                    callbackContext.success(obj);
                }
            },callbackContext);
        }
        else if (action.equals("remove")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {
                    boolean success= remove(fname);
                    if (success) {
                        notifyDelete(fname);
                        callbackContext.success();
                    } else {
                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
                    }
                }
            },callbackContext);
        }
        else if (action.equals("removeRecursively")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws FileExistsException, MalformedURLException, NoModificationAllowedException {
                    boolean success = removeRecursively(fname);
                    if (success) {
                        callbackContext.success();
                    } else {
                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
                    }
                }
            },callbackContext);
        }
        else if (action.equals("moveTo")) {
            final String fname=args.getString(0);
            final String newParent=args.getString(1);
            final String newName=args.getString(2);
            threadhelper( new FileOp( ){
                public void run() throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
                    JSONObject entry = transferTo(fname, newParent, newName, true);
                    callbackContext.success(entry);
                }
            },callbackContext);
        }
        else if (action.equals("copyTo")) {
            final String fname=args.getString(0);
            final String newParent=args.getString(1);
            final String newName=args.getString(2);
            threadhelper( new FileOp( ){
                public void run() throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
                    JSONObject entry = transferTo(fname, newParent, newName, false);
                    callbackContext.success(entry);
                }
            },callbackContext);
        }
        else if (action.equals("readEntries")) {
            final String fname=args.getString(0);
            threadhelper( new FileOp( ){
                public void run() throws FileNotFoundException, JSONException, MalformedURLException {
                    JSONArray entries = readEntries(fname);
                    callbackContext.success(entries);
                }
            },callbackContext);
        }
        else {
            return false;
        }
        return true;
    }

    /* helper to execute functions async and handle the result codes
     *
     */
    private void threadhelper(final FileOp f, final CallbackContext callbackContext){
        cordova.getThreadPool().execute(new Runnable() {
            public void run() {
                try {
                    f.run();
                } catch ( Exception e) {
                    e.printStackTrace();
                    if( e instanceof EncodingException){
                        callbackContext.error(FileUtils.ENCODING_ERR);
                    } else if(e instanceof FileNotFoundException) {
                        callbackContext.error(FileUtils.NOT_FOUND_ERR);
                    } else if(e instanceof FileExistsException) {
                        callbackContext.error(FileUtils.PATH_EXISTS_ERR);
                    } else if(e instanceof NoModificationAllowedException ) {
                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
                    } else if(e instanceof InvalidModificationException ) {
                        callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
                    } else if(e instanceof MalformedURLException ) {
                        callbackContext.error(FileUtils.ENCODING_ERR);
                    } else if(e instanceof IOException ) {
                        callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
                    } else if(e instanceof EncodingException ) {
                        callbackContext.error(FileUtils.ENCODING_ERR);
                    } else if(e instanceof TypeMismatchException ) {
                        callbackContext.error(FileUtils.TYPE_MISMATCH_ERR);
                    }
                }
            }
        });
    }

    /**
     * Need to check to see if we need to clean up the content store
     *
     * @param filePath the path to check
     */
    private void notifyDelete(String filePath) {
        String newFilePath = FileHelper.getRealPath(filePath, cordova);
        try {
            this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    MediaStore.Images.Media.DATA + " = ?",
                    new String[] { newFilePath });
        } catch (UnsupportedOperationException t) {
            // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
            // The ContentResolver applies only when the file was registered in the
            // first case, which is generally only the case with images.
        }
    }

    /**
     * Allows the user to look up the Entry for a file or directory referred to by a local URI.
     *
     * @param url of the file/directory to look up
     * @return a JSONObject representing a Entry from the filesystem
     * @throws MalformedURLException if the url is not valid
     * @throws FileNotFoundException if the file does not exist
     * @throws IOException if the user can't read the file
     * @throws JSONException
     */
    private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
        String decoded = URLDecoder.decode(url, "UTF-8");

        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(decoded);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.getEntryForLocalURL(inputURL);
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }   
    
    /**
     * Read the list of files from this directory.
     *
     * @param fileName the directory to read from
     * @return a JSONArray containing JSONObjects that represent Entry objects.
     * @throws FileNotFoundException if the directory is not found.
     * @throws JSONException
     * @throws MalformedURLException 
     */
    private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.readEntriesAtLocalURL(inputURL);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }

    /**
     * A setup method that handles the move/copy of files/directories
     *
     * @param fileName to be copied/moved
     * @param newParent is the location where the file will be copied/moved to
     * @param newName for the file directory to be called, if null use existing file name
     * @param move if false do a copy, if true do a move
     * @return a Entry object
     * @throws NoModificationAllowedException
     * @throws IOException
     * @throws InvalidModificationException
     * @throws EncodingException
     * @throws JSONException
     * @throws FileExistsException
     */
    private JSONObject transferTo(String srcURLstr, String destURLstr, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
        if (srcURLstr == null || destURLstr == null) {
            // either no source or no destination provided
        	throw new FileNotFoundException();
        }

        LocalFilesystemURL srcURL = new LocalFilesystemURL(srcURLstr);
        LocalFilesystemURL destURL = new LocalFilesystemURL(destURLstr);

        Filesystem srcFs = this.filesystemForURL(srcURL);
        Filesystem destFs = this.filesystemForURL(destURL);

        // Check for invalid file name
        if (newName != null && newName.contains(":")) {
            throw new EncodingException("Bad file name");
        }

        return destFs.copyFileToURL(destURL, newName, srcFs, srcURL, move);
    }

    /**
     * Deletes a directory and all of its contents, if any. In the event of an error
     * [e.g. trying to delete a directory that contains a file that cannot be removed],
     * some of the contents of the directory may be deleted.
     * It is an error to attempt to delete the root directory of a filesystem.
     *
     * @param filePath the directory to be removed
     * @return a boolean representing success of failure
     * @throws FileExistsException
     * @throws NoModificationAllowedException 
     * @throws MalformedURLException 
     */
    private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	// You can't delete the root directory.
        	if ("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath)) {
        		throw new NoModificationAllowedException("You can't delete the root directory");
        	}

        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.recursiveRemoveFileAtLocalURL(inputURL);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }


    /**
     * Deletes a file or directory. It is an error to attempt to delete a directory that is not empty.
     * It is an error to attempt to delete the root directory of a filesystem.
     *
     * @param filePath file or directory to be removed
     * @return a boolean representing success of failure
     * @throws NoModificationAllowedException
     * @throws InvalidModificationException
     * @throws MalformedURLException 
     */
    private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	// You can't delete the root directory.
        	if ("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath)) {

        		throw new NoModificationAllowedException("You can't delete the root directory");
        	}

        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.removeFileAtLocalURL(inputURL);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }

    /**
     * Creates or looks up a file.
     *
     * @param baseURLstr base directory
     * @param fileName file/directory to lookup or create
     * @param options specify whether to create or not
     * @param directory if true look up directory, if false look up file
     * @return a Entry object
     * @throws FileExistsException
     * @throws IOException
     * @throws TypeMismatchException
     * @throws EncodingException
     * @throws JSONException
     */
    private JSONObject getFile(String baseURLstr, String fileName, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.getFileForLocalURL(inputURL, fileName, options, directory);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }

    }

    /**
     * Look up the parent DirectoryEntry containing this Entry.
     * If this Entry is the root of its filesystem, its parent is itself.
     *
     * @param filePath
     * @return
     * @throws JSONException
     * @throws IOException 
     */
    private JSONObject getParent(String baseURLstr) throws JSONException, IOException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.getParentForLocalURL(inputURL);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }

    /**
     * Returns a File that represents the current state of the file that this FileEntry represents.
     *
     * @param filePath to entry
     * @return returns a JSONObject represent a W3C File object
     * @throws FileNotFoundException
     * @throws JSONException
     * @throws MalformedURLException 
     */
    private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        	return fs.getFileMetadataForLocalURL(inputURL);
        
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }

    /**
     * Requests a filesystem in which to store application data.
     *
     * @param type of file system requested
     * @return a JSONObject representing the file system
     * @throws IOException
     * @throws JSONException
     */
    private JSONObject requestFileSystem(int type) throws IOException, JSONException {
        JSONObject fs = new JSONObject();
        LocalFilesystemURL rootURL;
        if (type == TEMPORARY) {
            fs.put("name", "temporary");
            rootURL = new LocalFilesystemURL("filesystem://localhost/temporary/");
        }
        else if (type == PERSISTENT) {
            fs.put("name", "persistent");
            rootURL = new LocalFilesystemURL("filesystem://localhost/persistent/");
        }
        else {
            throw new IOException("No filesystem of type requested");
        }
        Filesystem rootFs = this.filesystemForURL(rootURL);
        fs.put("root", rootFs.getEntryForLocalURL(rootURL));
        return fs;
    }

    /**
     * Returns a JSON object representing the given File. Deprecated, as this is only used by
     * FileTransfer, and because it is a static method that should really be an instance method,
     * since it depends on the actual filesystem roots in use. Internal APIs should be modified
     * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin.
     *
     * @param file the File to convert
     * @return a JSON representation of the given File
     * @throws JSONException
     */
    @Deprecated
    public static JSONObject getEntry(File file) throws JSONException {
		JSONObject entry;
		
		if (filePlugin != null) {
			LocalFilesystem fs;
			fs = (LocalFilesystem) filePlugin.filesystems.get(0);
			entry = fs.makeEntryForFile(file, 0);
			if (entry != null) {
				return entry;
			}
			fs = (LocalFilesystem) filePlugin.filesystems.get(1);
			entry = fs.makeEntryForFile(file, 1);
			if (entry != null) {
				return entry;
			}			
		}
		return null;
    }

    /**
     * Read the contents of a file.
     * This is done in a background thread; the result is sent to the callback.
     *
     * @param filename          The name of the file.
     * @param start             Start position in the file.
     * @param end               End position to stop at (exclusive).
     * @param callbackContext   The context through which to send the result.
     * @param encoding          The encoding to return contents as.  Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
     * @param resultType        The desired type of data to send to the callback.
     * @return                  Contents of file.
     * @throws MalformedURLException 
     */
    public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        
            fs.readFileAtURL(inputURL, start, end, new ReadFileCallback() {
            	public void handleData(byte[] bytes, String contentType) {
            		try {
            			PluginResult result;
            			switch (resultType) {
            			case PluginResult.MESSAGE_TYPE_STRING:
            				result = new PluginResult(PluginResult.Status.OK, new String(bytes, encoding));
            				break;
            			case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
            				result = new PluginResult(PluginResult.Status.OK, bytes);
            				break;
            			case PluginResult.MESSAGE_TYPE_BINARYSTRING:
            				result = new PluginResult(PluginResult.Status.OK, bytes, true);
            				break;
            			default: // Base64.
            			byte[] base64 = Base64.encode(bytes, Base64.NO_WRAP);
            			String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII");
            			result = new PluginResult(PluginResult.Status.OK, s);
            			}

            			callbackContext.sendPluginResult(result);
            		} catch (IOException e) {
            			Log.d(LOG_TAG, e.getLocalizedMessage());
            			callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
                    }
            	}
            });


        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        } catch (FileNotFoundException e) {
        	callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));
        } catch (IOException e) {
        	Log.d(LOG_TAG, e.getLocalizedMessage());
        	callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
        }
    }


    /**
     * Write contents of file.
     *
     * @param filename			The name of the file.
     * @param data				The contents of the file.
     * @param offset			The position to begin writing the file.
     * @param isBinary          True if the file contents are base64-encoded binary data
     * @throws FileNotFoundException, IOException
     * @throws NoModificationAllowedException
     */
    /**/
    public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        
            long x = fs.writeToFileAtURL(inputURL, data, offset, isBinary); Log.d("TEST",srcURLstr + ": "+x); return x;
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
        
    }

    /**
     * Truncate the file to size
     *
     * @param filename
     * @param size
     * @throws FileNotFoundException, IOException
     * @throws NoModificationAllowedException
     */
    private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
        try {
        	LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
        	Filesystem fs = this.filesystemForURL(inputURL);
        	if (fs == null) {
        		throw new MalformedURLException("No installed handlers for this URL");
        	}
        
            return fs.truncateFileAtURL(inputURL, size);
        } catch (IllegalArgumentException e) {
        	throw new MalformedURLException("Unrecognized filesystem URL");
        }
    }
}
