///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB                               //
//                                                                           //
// All rights reserved. This program and the accompanying materials          //
// are made available under the terms of the Eclipse Public License v2.0     //
// which accompanies this distribution, and is available at                  //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                 //
///////////////////////////////////////////////////////////////////////////////
function FileHandler() {

    ////////////////////////// MOCK OF FILE OPERATIONS //////////////////////////

    var fileCache = {};

    // The existing directories and files, this must be updated when there is a change
    var contentOnDisc = [
        REPLACETHIS
    ];

    /**
        Since saving is not allowed by the browsers, we use a hashmap with the ulrs as keys
     */
    this.putFile = function (url, data, callback) {
        fileCache[url] = data;
        callback(true, data);
    };

    /**
        A function to remove duplicate items from a list
     */
    function uniq(list) {
        var seen = {};
        return list.filter(function (item) {
            return seen.hasOwnProperty(item) ? false : (seen[item] = true);
        });
    }

    /**
        Since there is no list dir command in a local browser, we have to return contentOnDisc from a predefined list
     */
    this.getDirectory = function (url, callback) {
        var contentList = [];

        if (url != "/" && url.startsWith("/")) {
            url = url.substr(1);
        }
        
        // find the contentOnDisc in the directory
        for (var i = 0; i < contentOnDisc.length; ++i) {
            if (contentOnDisc[i].substr(0, url.length) == url && contentOnDisc[i].length != url.length) {
                var index = contentOnDisc[i].indexOf("/", url.length + 1);
                if (index != -1) {
                    contentList.push(contentOnDisc[i].substring(0, index));
                } else {
                    contentList.push(contentOnDisc[i]);
                }
            }
            
            if (url == "/" && contentOnDisc[i].indexOf("/") == -1) {
                contentList.push(contentOnDisc[i]);
            }
        }
        
        // find the fileCache in the directory
        for (var key in fileCache) {
            if (fileCache.hasOwnProperty(key) && key.substr(0, url.length) == url) {
                var index = key.indexOf("/", url.length + 1);
                if (index != -1) {
                    contentList.push(key.substring(0, index));
                } else {
                    contentList.push(key);
                }
            }
        }
        
        var fileList = [];
        var listOfNames = uniq(contentList);
        for (var i = 0; i < listOfNames.length; ++i) {
            var contentType;
            if (listOfNames[i].indexOf('.') == -1) {
                contentType = "-d"
            } else {
                contentType = "-f"
            }
            fileList.push({
                "contentType" : contentType,
                "fileName" : listOfNames[i],
                "size" : 0,
                "timeStamp" : 0
            });
        }
        
        callback(fileList);
    };

    this.createDirectory = function (url, callback) {
        if (contentOnDisc.indexOf(url) == -1) {
            contentOnDisc.push(url);
        }
        callback(true);
    };

    this.delDirectory = function (url, callback) {
        var i = 0;
        while (i < contentOnDisc.length) {
            if (contentOnDisc[i].substr(0, url.length) == url) {
                contentOnDisc.splice(i, 1);
            } else {
                ++i;
            }
        }

        var todelete = [];
        for (var key in fileCache) {
            if (fileCache.hasOwnProperty(key) && key.substr(0, url.length) == url) {
                todelete.push(key);
            }
        }

        for (var j = 0; j < todelete.length; ++j) {
            delete fileCache[todelete[j]];
        }

        callback(true);
    };

    this.loadFile = function (url, callback) {

        if (fileCache.hasOwnProperty(url)) {
            callback(true, fileCache[url]);
            return;
        }

        function success(data, textStatus, jqXHR) {
            callback(true, data);
        }

        function error(data, textStatus, jqXHR) {
            callback(false, "Loading: " + textStatus + " " + jqXHR);
        }

        return $.ajax({
            url : url,
            type : 'GET',
            success : success,
            error : error,
            dataType : "text",
            data : "",
            async : false
        });
    };

    this.importJsFile = function (file, p_callback) {
        var v_callback = p_callback;
        function success(data, textStatus, jqXHR) {
            v_callback(true);
        }

        function error(data, textStatus, jqXHR) {
            v_callback(false, "Loading: " + textStatus + " " + jqXHR + " " + file);
        }

        $.ajax({
            url : file,
            dataType : "script",
            success : success,
            error : error,
            async : false
        });
    };    
    
    
    this.loadCss = function(hmtlContentId, cssFile, callback) {
        $("#" + hmtlContentId).load(cssFile, callback);
    };
    
    this.loadCssFiles = function(cssFiles, id) {
        for (var i = 0; i < cssFiles.length; ++i) {
            // html ids should not contain / and . so we replace them with _
            var cssId = cssFiles[i].replace(/[\/\.]/gi, "_");
            $("#" + id).prepend('<style id="' + cssId + '" type="text/css"></style>');
            this.loadCss(cssId, cssFiles[i]);
        }
    };
}