/*
 *
 * 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.
 *
 */

(function () {
    /* global require, exports, module */
    /* global FILESYSTEM_PREFIX */
    /* global IDBKeyRange */
    /* global FileReader */
    /* global atob, btoa, Blob */

    /* Heavily based on https://github.com/ebidel/idb.filesystem.js */

    // For chrome we don't need to implement proxy methods
    // All functionality can be accessed natively.
    if (require('./isChrome')()) {
        var pathsPrefix = {
            // Read-only directory where the application is installed.
            applicationDirectory: location.origin + '/',
            // Where to put app-specific data files.
            dataDirectory: 'filesystem:file:///persistent/',
            // Cached files that should survive app restarts.
            // Apps should not rely on the OS to delete files in here.
            cacheDirectory: 'filesystem:file:///temporary/'
        };

        exports.requestAllPaths = function (successCallback) {
            successCallback(pathsPrefix);
        };

        require('cordova/exec/proxy').add('File', module.exports);
        return;
    }

    var LocalFileSystem = require('./LocalFileSystem');
    var FileSystem = require('./FileSystem');
    var FileEntry = require('./FileEntry');
    var FileError = require('./FileError');
    var DirectoryEntry = require('./DirectoryEntry');
    var File = require('./File');

    (function (exports, global) {
        var fs_ = null;

        var idb_ = {};
        idb_.db = null;
        var FILE_STORE_ = 'entries';

        var DIR_SEPARATOR = '/';

        var pathsPrefix = {
            // Read-only directory where the application is installed.
            applicationDirectory: location.origin + '/',
            // Where to put app-specific data files.
            dataDirectory: 'file:///persistent/',
            // Cached files that should survive app restarts.
            // Apps should not rely on the OS to delete files in here.
            cacheDirectory: 'file:///temporary/'
        };

        var unicodeLastChar = 65535;

        /** * Exported functionality ***/

        exports.requestFileSystem = function (successCallback, errorCallback, args) {
            var type = args[0];

            if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent';
            var storageName = (location.protocol + location.host).replace(/:/g, '_');

            var root = new DirectoryEntry('', DIR_SEPARATOR);
            fs_ = new FileSystem(name, root);

            idb_.open(
                storageName,
                function () {
                    successCallback(fs_);
                },
                errorCallback
            );
        };

        // Overridden by Android, BlackBerry 10 and iOS to populate fsMap
        require('./fileSystems').getFs = function (name, callback) {
            callback(new FileSystem(name, fs_.root));
        };

        // list a directory's contents (files and folders).
        exports.readEntries = function (successCallback, errorCallback, args) {
            var fullPath = args[0];

            if (typeof successCallback !== 'function') {
                throw Error('Expected successCallback argument.');
            }

            var path = resolveToFullPath_(fullPath);

            exports.getDirectory(
                function () {
                    idb_.getAllEntries(
                        path.fullPath + DIR_SEPARATOR,
                        path.storagePath,
                        function (entries) {
                            successCallback(entries);
                        },
                        errorCallback
                    );
                },
                function () {
                    if (errorCallback) {
                        errorCallback(FileError.NOT_FOUND_ERR);
                    }
                },
                [path.storagePath, path.fullPath, { create: false }]
            );
        };

        exports.getFile = function (successCallback, errorCallback, args) {
            var fullPath = args[0];
            var path = args[1];
            var options = args[2] || {};

            // Create an absolute path if we were handed a relative one.
            path = resolveToFullPath_(fullPath, path);

            idb_.get(
                path.storagePath,
                function (fileEntry) {
                    if (options.create === true && options.exclusive === true && fileEntry) {
                        // If create and exclusive are both true, and the path already exists,
                        // getFile must fail.

                        if (errorCallback) {
                            errorCallback(FileError.PATH_EXISTS_ERR);
                        }
                    } else if (options.create === true && !fileEntry) {
                        // If create is true, the path doesn't exist, and no other error occurs,
                        // getFile must create it as a zero-length file and return a corresponding
                        // FileEntry.
                        var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));

                        newFileEntry.file_ = new MyFile({
                            size: 0,
                            name: newFileEntry.name,
                            lastModifiedDate: new Date(),
                            storagePath: path.storagePath
                        });

                        idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
                    } else if (options.create === true && fileEntry) {
                        if (fileEntry.isFile) {
                            // Overwrite file, delete then create new.
                            idb_.delete(
                                path.storagePath,
                                function () {
                                    var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));

                                    newFileEntry.file_ = new MyFile({
                                        size: 0,
                                        name: newFileEntry.name,
                                        lastModifiedDate: new Date(),
                                        storagePath: path.storagePath
                                    });

                                    idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
                                },
                                errorCallback
                            );
                        } else {
                            if (errorCallback) {
                                errorCallback(FileError.INVALID_MODIFICATION_ERR);
                            }
                        }
                    } else if ((!options.create || options.create === false) && !fileEntry) {
                        // If create is not true and the path doesn't exist, getFile must fail.
                        if (errorCallback) {
                            errorCallback(FileError.NOT_FOUND_ERR);
                        }
                    } else if ((!options.create || options.create === false) && fileEntry && fileEntry.isDirectory) {
                        // If create is not true and the path exists, but is a directory, getFile
                        // must fail.
                        if (errorCallback) {
                            errorCallback(FileError.TYPE_MISMATCH_ERR);
                        }
                    } else {
                        // Otherwise, if no other error occurs, getFile must return a FileEntry
                        // corresponding to path.

                        successCallback(fileEntryFromIdbEntry(fileEntry));
                    }
                },
                errorCallback
            );
        };

        exports.getFileMetadata = function (successCallback, errorCallback, args) {
            var fullPath = args[0];

            exports.getFile(
                function (fileEntry) {
                    successCallback(
                        new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate, fileEntry.file_.size)
                    );
                },
                errorCallback,
                [fullPath, null]
            );
        };

        exports.getMetadata = function (successCallback, errorCallback, args) {
            exports.getFile(
                function (fileEntry) {
                    successCallback({
                        modificationTime: fileEntry.file_.lastModifiedDate,
                        size: fileEntry.file_.lastModifiedDate
                    });
                },
                errorCallback,
                args
            );
        };

        exports.setMetadata = function (successCallback, errorCallback, args) {
            var fullPath = args[0];
            var metadataObject = args[1];

            exports.getFile(
                function (fileEntry) {
                    fileEntry.file_.lastModifiedDate = metadataObject.modificationTime;
                    idb_.put(fileEntry, fileEntry.file_.storagePath, successCallback, errorCallback);
                },
                errorCallback,
                [fullPath, null]
            );
        };

        exports.write = function (successCallback, errorCallback, args) {
            var fileName = args[0];
            var data = args[1];
            var position = args[2];

            if (!data) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            if (typeof data === 'string' || data instanceof String) {
                data = new Blob([data]);
            }

            exports.getFile(
                function (fileEntry) {
                    var blob_ = fileEntry.file_.blob_;

                    if (!blob_) {
                        blob_ = new Blob([data], { type: data.type });
                    } else {
                        // Calc the head and tail fragments
                        var head = blob_.slice(0, position);
                        var tail = blob_.slice(position + (data.size || data.byteLength));

                        // Calc the padding
                        var padding = position - head.size;
                        if (padding < 0) {
                            padding = 0;
                        }

                        // Do the "write". In fact, a full overwrite of the Blob.
                        blob_ = new Blob([head, new Uint8Array(padding), data, tail], { type: data.type });
                    }

                    // Set the blob we're writing on this file entry so we can recall it later.
                    fileEntry.file_.blob_ = blob_;
                    fileEntry.file_.lastModifiedDate = new Date() || null;
                    fileEntry.file_.size = blob_.size;
                    fileEntry.file_.name = blob_.name;
                    fileEntry.file_.type = blob_.type;

                    idb_.put(
                        fileEntry,
                        fileEntry.file_.storagePath,
                        function () {
                            successCallback(data.size || data.byteLength);
                        },
                        errorCallback
                    );
                },
                errorCallback,
                [fileName, null]
            );
        };

        exports.readAsText = function (successCallback, errorCallback, args) {
            var fileName = args[0];
            var enc = args[1];
            var startPos = args[2];
            var endPos = args[3];

            readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback);
        };

        exports.readAsDataURL = function (successCallback, errorCallback, args) {
            var fileName = args[0];
            var startPos = args[1];
            var endPos = args[2];

            readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback);
        };

        exports.readAsBinaryString = function (successCallback, errorCallback, args) {
            var fileName = args[0];
            var startPos = args[1];
            var endPos = args[2];

            readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback);
        };

        exports.readAsArrayBuffer = function (successCallback, errorCallback, args) {
            var fileName = args[0];
            var startPos = args[1];
            var endPos = args[2];

            readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback);
        };

        exports.removeRecursively = exports.remove = function (successCallback, errorCallback, args) {
            if (typeof successCallback !== 'function') {
                throw Error('Expected successCallback argument.');
            }

            var fullPath = resolveToFullPath_(args[0]).storagePath;
            if (fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) {
                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
                return;
            }

            function deleteEntry (isDirectory) {
                // TODO: This doesn't protect against directories that have content in it.
                // Should throw an error instead if the dirEntry is not empty.
                idb_.delete(
                    fullPath,
                    function () {
                        successCallback();
                    },
                    function () {
                        if (errorCallback) {
                            errorCallback();
                        }
                    },
                    isDirectory
                );
            }

            // We need to to understand what we are deleting:
            exports.getDirectory(
                function (entry) {
                    deleteEntry(entry.isDirectory);
                },
                function () {
                    // DirectoryEntry was already deleted or entry is FileEntry
                    deleteEntry(false);
                },
                [fullPath, null, { create: false }]
            );
        };

        exports.getDirectory = function (successCallback, errorCallback, args) {
            var fullPath = args[0];
            var path = args[1];
            var options = args[2];

            // Create an absolute path if we were handed a relative one.
            path = resolveToFullPath_(fullPath, path);

            idb_.get(
                path.storagePath,
                function (folderEntry) {
                    if (!options) {
                        options = {};
                    }

                    if (options.create === true && options.exclusive === true && folderEntry) {
                        // If create and exclusive are both true, and the path already exists,
                        // getDirectory must fail.
                        if (errorCallback) {
                            errorCallback(FileError.PATH_EXISTS_ERR);
                        }
                        // There is a strange bug in mobilespec + FF, which results in coming to multiple else-if's
                        // so we are shielding from it with returns.
                        return;
                    }

                    if (options.create === true && !folderEntry) {
                        // If create is true, the path doesn't exist, and no other error occurs,
                        // getDirectory must create it as a zero-length file and return a corresponding
                        // MyDirectoryEntry.
                        var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));

                        idb_.put(dirEntry, path.storagePath, successCallback, errorCallback);
                        return;
                    }

                    if (options.create === true && folderEntry) {
                        if (folderEntry.isDirectory) {
                            // IDB won't save methods, so we need re-create the MyDirectoryEntry.
                            successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
                        } else {
                            if (errorCallback) {
                                errorCallback(FileError.INVALID_MODIFICATION_ERR);
                            }
                        }
                        return;
                    }

                    if ((!options.create || options.create === false) && !folderEntry) {
                        // Handle root special. It should always exist.
                        if (path.fullPath === DIR_SEPARATOR) {
                            successCallback(fs_.root);
                            return;
                        }

                        // If create is not true and the path doesn't exist, getDirectory must fail.
                        if (errorCallback) {
                            errorCallback(FileError.NOT_FOUND_ERR);
                        }

                        return;
                    }
                    if ((!options.create || options.create === false) && folderEntry && folderEntry.isFile) {
                        // If create is not true and the path exists, but is a file, getDirectory
                        // must fail.
                        if (errorCallback) {
                            errorCallback(FileError.TYPE_MISMATCH_ERR);
                        }
                        return;
                    }

                    // Otherwise, if no other error occurs, getDirectory must return a
                    // MyDirectoryEntry corresponding to path.

                    // IDB won't' save methods, so we need re-create MyDirectoryEntry.
                    successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
                },
                errorCallback
            );
        };

        exports.getParent = function (successCallback, errorCallback, args) {
            if (typeof successCallback !== 'function') {
                throw Error('Expected successCallback argument.');
            }

            var fullPath = args[0];
            // fullPath is like this:
            // file:///persistent/path/to/file or
            // file:///persistent/path/to/directory/

            if (fullPath === DIR_SEPARATOR || fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) {
                successCallback(fs_.root);
                return;
            }

            // To delete all slashes at the end
            while (fullPath[fullPath.length - 1] === '/') {
                fullPath = fullPath.substr(0, fullPath.length - 1);
            }

            var pathArr = fullPath.split(DIR_SEPARATOR);
            pathArr.pop();
            var parentName = pathArr.pop();
            var path = pathArr.join(DIR_SEPARATOR) + DIR_SEPARATOR;

            // To get parent of root files
            var joined = path + parentName + DIR_SEPARATOR; // is like this: file:///persistent/
            if (joined === pathsPrefix.cacheDirectory || joined === pathsPrefix.dataDirectory) {
                exports.getDirectory(successCallback, errorCallback, [joined, DIR_SEPARATOR, { create: false }]);
                return;
            }

            exports.getDirectory(successCallback, errorCallback, [path, parentName, { create: false }]);
        };

        exports.copyTo = function (successCallback, errorCallback, args) {
            var srcPath = args[0];
            var parentFullPath = args[1];
            var name = args[2];

            if (name.indexOf('/') !== -1 || srcPath === parentFullPath + name) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }

                return;
            }

            // Read src file
            exports.getFile(
                function (srcFileEntry) {
                    var path = resolveToFullPath_(parentFullPath);
                    // Check directory
                    exports.getDirectory(
                        function () {
                            // Create dest file
                            exports.getFile(
                                function (dstFileEntry) {
                                    exports.write(
                                        function () {
                                            successCallback(dstFileEntry);
                                        },
                                        errorCallback,
                                        [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]
                                    );
                                },
                                errorCallback,
                                [parentFullPath, name, { create: true }]
                            );
                        },
                        function () {
                            if (errorCallback) {
                                errorCallback(FileError.NOT_FOUND_ERR);
                            }
                        },
                        [path.storagePath, null, { create: false }]
                    );
                },
                errorCallback,
                [srcPath, null]
            );
        };

        exports.moveTo = function (successCallback, errorCallback, args) {
            var srcPath = args[0];

            exports.copyTo(
                function (fileEntry) {
                    exports.remove(
                        function () {
                            successCallback(fileEntry);
                        },
                        errorCallback,
                        [srcPath]
                    );
                },
                errorCallback,
                args
            );
        };

        exports.resolveLocalFileSystemURI = function (successCallback, errorCallback, args) {
            var path = args[0];

            // Ignore parameters
            if (path.indexOf('?') !== -1) {
                path = String(path).split('?')[0];
            }

            // support for encodeURI
            if (/%5/g.test(path) || /%20/g.test(path)) {
                path = decodeURI(path);
            }

            if (path.trim()[0] === '/') {
                if (errorCallback) {
                    errorCallback(FileError.ENCODING_ERR);
                }
                return;
            }

            // support for cdvfile
            if (path.trim().substr(0, 7) === 'cdvfile') {
                if (path.indexOf('cdvfile://localhost') === -1) {
                    if (errorCallback) {
                        errorCallback(FileError.ENCODING_ERR);
                    }
                    return;
                }

                var indexPersistent = path.indexOf('persistent');
                var indexTemporary = path.indexOf('temporary');

                // cdvfile://localhost/persistent/path/to/file
                if (indexPersistent !== -1) {
                    path = 'file:///persistent' + path.substr(indexPersistent + 10);
                } else if (indexTemporary !== -1) {
                    path = 'file:///temporary' + path.substr(indexTemporary + 9);
                } else {
                    if (errorCallback) {
                        errorCallback(FileError.ENCODING_ERR);
                    }
                    return;
                }
            }

            // to avoid path form of '///path/to/file'
            function handlePathSlashes (path) {
                var cutIndex = 0;
                for (var i = 0; i < path.length - 1; i++) {
                    if (path[i] === DIR_SEPARATOR && path[i + 1] === DIR_SEPARATOR) {
                        cutIndex = i + 1;
                    } else break;
                }

                return path.substr(cutIndex);
            }

            // Handle localhost containing paths (see specs )
            if (path.indexOf('file://localhost/') === 0) {
                path = path.replace('file://localhost/', 'file:///');
            }

            if (path.indexOf(pathsPrefix.dataDirectory) === 0) {
                path = path.substring(pathsPrefix.dataDirectory.length - 1);
                path = handlePathSlashes(path);

                exports.requestFileSystem(
                    function () {
                        exports.getFile(
                            successCallback,
                            function () {
                                exports.getDirectory(successCallback, errorCallback, [pathsPrefix.dataDirectory, path, { create: false }]);
                            },
                            [pathsPrefix.dataDirectory, path, { create: false }]
                        );
                    },
                    errorCallback,
                    [LocalFileSystem.PERSISTENT]
                );
            } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) {
                path = path.substring(pathsPrefix.cacheDirectory.length - 1);
                path = handlePathSlashes(path);

                exports.requestFileSystem(
                    function () {
                        exports.getFile(
                            successCallback,
                            function () {
                                exports.getDirectory(successCallback, errorCallback, [pathsPrefix.cacheDirectory, path, { create: false }]);
                            },
                            [pathsPrefix.cacheDirectory, path, { create: false }]
                        );
                    },
                    errorCallback,
                    [LocalFileSystem.TEMPORARY]
                );
            } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) {
                path = path.substring(pathsPrefix.applicationDirectory.length);
                // TODO: need to cut out redundant slashes?

                var xhr = new XMLHttpRequest();
                xhr.open('GET', path, true);
                xhr.onreadystatechange = function () {
                    if (xhr.status === 200 && xhr.readyState === 4) {
                        exports.requestFileSystem(
                            function (fs) {
                                fs.name = location.hostname;

                                // TODO: need to call exports.getFile(...) to handle errors correct
                                fs.root.getFile(path, { create: true }, writeFile, errorCallback);
                            },
                            errorCallback,
                            [LocalFileSystem.PERSISTENT]
                        );
                    }
                };

                xhr.onerror = function () {
                    if (errorCallback) {
                        errorCallback(FileError.NOT_READABLE_ERR);
                    }
                };

                xhr.send();
            } else {
                if (errorCallback) {
                    errorCallback(FileError.NOT_FOUND_ERR);
                }
            }

            function writeFile (entry) {
                entry.createWriter(function (fileWriter) {
                    fileWriter.onwriteend = function (evt) {
                        if (!evt.target.error) {
                            entry.filesystemName = location.hostname;
                            successCallback(entry);
                        }
                    };
                    fileWriter.onerror = function () {
                        if (errorCallback) {
                            errorCallback(FileError.NOT_READABLE_ERR);
                        }
                    };
                    fileWriter.write(new Blob([xhr.response]));
                }, errorCallback);
            }
        };

        exports.requestAllPaths = function (successCallback) {
            successCallback(pathsPrefix);
        };

        /** * Helpers ***/

        /**
         * Interface to wrap the native File interface.
         *
         * This interface is necessary for creating zero-length (empty) files,
         * something the Filesystem API allows you to do. Unfortunately, File's
         * constructor cannot be called directly, making it impossible to instantiate
         * an empty File in JS.
         *
         * @param {Object} opts Initial values.
         * @constructor
         */
        function MyFile (opts) {
            var blob_ = new Blob();

            this.size = opts.size || 0;
            this.name = opts.name || '';
            this.type = opts.type || '';
            this.lastModifiedDate = opts.lastModifiedDate || null;
            this.storagePath = opts.storagePath || '';

            // Need some black magic to correct the object's size/name/type based on the
            // blob that is saved.
            Object.defineProperty(this, 'blob_', {
                enumerable: true,
                get: function () {
                    return blob_;
                },
                set: function (val) {
                    blob_ = val;
                    this.size = blob_.size;
                    this.name = blob_.name;
                    this.type = blob_.type;
                    this.lastModifiedDate = blob_.lastModifiedDate;
                }.bind(this)
            });
        }

        MyFile.prototype.constructor = MyFile;

        var MyFileHelper = {
            toJson: function (myFile, success) {
                /*
                    Safari private browse mode cannot store Blob object to indexeddb.
                    Then use pure json object instead of Blob object.
                */
                var fr = new FileReader();
                fr.onload = function (ev) {
                    var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(fr.result)));
                    success({
                        opt: {
                            size: myFile.size,
                            name: myFile.name,
                            type: myFile.type,
                            lastModifiedDate: myFile.lastModifiedDate,
                            storagePath: myFile.storagePath
                        },
                        base64: base64
                    });
                };
                fr.readAsArrayBuffer(myFile.blob_);
            },
            setBase64: function (myFile, base64) {
                if (base64) {
                    var arrayBuffer = new Uint8Array(
                        [].map.call(atob(base64), function (c) {
                            return c.charCodeAt(0);
                        })
                    ).buffer;

                    myFile.blob_ = new Blob([arrayBuffer], { type: myFile.type });
                } else {
                    myFile.blob_ = new Blob();
                }
            }
        };

        // When saving an entry, the fullPath should always lead with a slash and never
        // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute
        // one. This method ensures path is legit!
        function resolveToFullPath_ (cwdFullPath, path) {
            path = path || '';
            var fullPath = path;
            var prefix = '';

            cwdFullPath = cwdFullPath || DIR_SEPARATOR;
            if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) {
                prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
                cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
            }

            var relativePath = path[0] !== DIR_SEPARATOR;
            if (relativePath) {
                fullPath = cwdFullPath;
                if (cwdFullPath !== DIR_SEPARATOR) {
                    fullPath += DIR_SEPARATOR + path;
                } else {
                    fullPath += path;
                }
            }

            // Remove doubled separator substrings
            var re = new RegExp(DIR_SEPARATOR + DIR_SEPARATOR, 'g');
            fullPath = fullPath.replace(re, DIR_SEPARATOR);

            // Adjust '..'s by removing parent directories when '..' flows in path.
            var parts = fullPath.split(DIR_SEPARATOR);
            for (var i = 0; i < parts.length; ++i) {
                var part = parts[i];
                if (part === '..') {
                    parts[i - 1] = '';
                    parts[i] = '';
                }
            }
            fullPath = parts
                .filter(function (el) {
                    return el;
                })
                .join(DIR_SEPARATOR);

            // Add back in leading slash.
            if (fullPath[0] !== DIR_SEPARATOR) {
                fullPath = DIR_SEPARATOR + fullPath;
            }

            // Replace './' by current dir. ('./one/./two' -> one/two)
            fullPath = fullPath.replace(/\.\//g, DIR_SEPARATOR);

            // Replace '//' with '/'.
            fullPath = fullPath.replace(/\/\//g, DIR_SEPARATOR);

            // Replace '/.' with '/'.
            fullPath = fullPath.replace(/\/\./g, DIR_SEPARATOR);

            // Remove '/' if it appears on the end.
            if (fullPath[fullPath.length - 1] === DIR_SEPARATOR && fullPath !== DIR_SEPARATOR) {
                fullPath = fullPath.substring(0, fullPath.length - 1);
            }

            var storagePath = prefix + fullPath;
            storagePath = decodeURI(storagePath);
            fullPath = decodeURI(fullPath);

            return {
                storagePath: storagePath,
                fullPath: fullPath,
                fileName: fullPath.split(DIR_SEPARATOR).pop(),
                fsName: prefix.split(DIR_SEPARATOR).pop()
            };
        }

        function fileEntryFromIdbEntry (fileEntry) {
            // IDB won't save methods, so we need re-create the FileEntry.
            var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.filesystem);
            clonedFileEntry.file_ = fileEntry.file_;

            return clonedFileEntry;
        }

        function readAs (what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) {
            exports.getFile(
                function (fileEntry) {
                    var fileReader = new FileReader();
                    var blob = fileEntry.file_.blob_.slice(startPos, endPos);

                    fileReader.onload = function (e) {
                        successCallback(e.target.result);
                    };

                    fileReader.onerror = errorCallback;

                    switch (what) {
                    case 'text':
                        fileReader.readAsText(blob, encoding);
                        break;
                    case 'dataURL':
                        fileReader.readAsDataURL(blob);
                        break;
                    case 'arrayBuffer':
                        fileReader.readAsArrayBuffer(blob);
                        break;
                    case 'binaryString':
                        fileReader.readAsBinaryString(blob);
                        break;
                    }
                },
                errorCallback,
                [fullPath, null]
            );
        }

        /** * Core logic to handle IDB operations ***/

        idb_.open = function (dbName, successCallback, errorCallback) {
            var self = this;

            // TODO: FF 12.0a1 isn't liking a db name with : in it.
            var request = indexedDB.open(dbName.replace(':', '_') /*, 1 /*version */);

            request.onerror = errorCallback || onError;

            request.onupgradeneeded = function (e) {
                // First open was called or higher db version was used.

                // console.log('onupgradeneeded: oldVersion:' + e.oldVersion,
                //           'newVersion:' + e.newVersion);

                self.db = e.target.result;
                self.db.onerror = onError;

                if (!self.db.objectStoreNames.contains(FILE_STORE_)) {
                    self.db.createObjectStore(FILE_STORE_ /*, {keyPath: 'id', autoIncrement: true} */);
                }
            };

            request.onsuccess = function (e) {
                self.db = e.target.result;
                self.db.onerror = onError;
                successCallback(e);
            };

            request.onblocked = errorCallback || onError;
        };

        idb_.close = function () {
            this.db.close();
            this.db = null;
        };

        idb_.get = function (fullPath, successCallback, errorCallback) {
            if (!this.db) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            var tx = this.db.transaction([FILE_STORE_], 'readonly');

            var request = tx.objectStore(FILE_STORE_).get(fullPath);

            tx.onabort = errorCallback || onError;
            tx.oncomplete = function () {
                var entry = request.result;
                if (entry && entry.file_json) {
                    /*
                        Safari private browse mode cannot store Blob object to indexeddb.
                        Then use pure json object instead of Blob object.
                    */
                    entry.file_ = new MyFile(entry.file_json.opt);
                    MyFileHelper.setBase64(entry.file_, entry.file_json.base64);
                    delete entry.file_json;
                }
                successCallback(entry);
            };
        };

        idb_.getAllEntries = function (fullPath, storagePath, successCallback, errorCallback) {
            if (!this.db) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            var results = [];

            if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) {
                storagePath = storagePath.substring(0, storagePath.length - 1);
            }

            var range = IDBKeyRange.bound(
                storagePath + DIR_SEPARATOR + ' ',
                storagePath + DIR_SEPARATOR + String.fromCharCode(unicodeLastChar)
            );

            var tx = this.db.transaction([FILE_STORE_], 'readonly');
            tx.onabort = errorCallback || onError;
            tx.oncomplete = function () {
                results = results.filter(function (val) {
                    var pathWithoutSlash = val.fullPath;

                    if (val.fullPath[val.fullPath.length - 1] === DIR_SEPARATOR) {
                        pathWithoutSlash = pathWithoutSlash.substr(0, pathWithoutSlash.length - 1);
                    }

                    var valPartsLen = pathWithoutSlash.split(DIR_SEPARATOR).length;
                    var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;

                    /* Input fullPath parameter  equals '//' for root folder */
                    /* Entries in root folder has valPartsLen equals 2 (see below) */
                    if (fullPath[fullPath.length - 1] === DIR_SEPARATOR && fullPath.trim().length === 2) {
                        fullPathPartsLen = 1;
                    } else if (fullPath[fullPath.length - 1] === DIR_SEPARATOR) {
                        fullPathPartsLen = fullPath.substr(0, fullPath.length - 1).split(DIR_SEPARATOR).length;
                    } else {
                        fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;
                    }

                    if (valPartsLen === fullPathPartsLen + 1) {
                        // If this a subfolder and entry is a direct child, include it in
                        // the results. Otherwise, it's not an entry of this folder.
                        return val;
                    } else return false;
                });

                successCallback(results);
            };

            var request = tx.objectStore(FILE_STORE_).openCursor(range);

            request.onsuccess = function (e) {
                var cursor = e.target.result;
                if (cursor) {
                    var val = cursor.value;

                    results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.filesystem));
                    cursor.continue();
                }
            };
        };

        idb_.delete = function (fullPath, successCallback, errorCallback, isDirectory) {
            if (!idb_.db) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            var tx = this.db.transaction([FILE_STORE_], 'readwrite');
            tx.oncomplete = successCallback;
            tx.onabort = errorCallback || onError;
            tx.oncomplete = function () {
                if (isDirectory) {
                    // We delete nested files and folders after deleting parent folder
                    // We use ranges: https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange
                    fullPath = fullPath + DIR_SEPARATOR;

                    // Range contains all entries in the form fullPath<symbol> where
                    // symbol in the range from ' ' to symbol which has code `unicodeLastChar`
                    var range = IDBKeyRange.bound(fullPath + ' ', fullPath + String.fromCharCode(unicodeLastChar));

                    var newTx = this.db.transaction([FILE_STORE_], 'readwrite');
                    newTx.oncomplete = successCallback;
                    newTx.onabort = errorCallback || onError;
                    newTx.objectStore(FILE_STORE_).delete(range);
                } else {
                    successCallback();
                }
            };
            tx.objectStore(FILE_STORE_).delete(fullPath);
        };

        idb_.put = function (entry, storagePath, successCallback, errorCallback, retry) {
            if (!this.db) {
                if (errorCallback) {
                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
                }
                return;
            }

            var tx = this.db.transaction([FILE_STORE_], 'readwrite');
            tx.onabort = errorCallback || onError;
            tx.oncomplete = function () {
                // TODO: Error is thrown if we pass the request event back instead.
                successCallback(entry);
            };

            try {
                tx.objectStore(FILE_STORE_).put(entry, storagePath);
            } catch (e) {
                if (e.name === 'DataCloneError') {
                    tx.oncomplete = null;
                    /*
                        Safari private browse mode cannot store Blob object to indexeddb.
                        Then use pure json object instead of Blob object.
                    */

                    var successCallback2 = function (entry) {
                        entry.file_ = new MyFile(entry.file_json.opt);
                        delete entry.file_json;
                        successCallback(entry);
                    };

                    if (!retry) {
                        if (entry.file_ && entry.file_ instanceof MyFile && entry.file_.blob_) {
                            MyFileHelper.toJson(entry.file_, function (json) {
                                entry.file_json = json;
                                delete entry.file_;
                                idb_.put(entry, storagePath, successCallback2, errorCallback, true);
                            });
                            return;
                        }
                    }
                }
                throw e;
            }
        };

        // Global error handler. Errors bubble from request, to transaction, to db.
        function onError (e) {
            switch (e.target.errorCode) {
            case 12:
                console.log('Error - Attempt to open db with a lower version than the ' + 'current one.');
                break;
            default:
                console.log('errorCode: ' + e.target.errorCode);
            }

            console.log(e, e.code, e.message);
        }
    })(module.exports, window);

    require('cordova/exec/proxy').add('File', module.exports);
})();
