// 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 GenericTask(p_function) {
    "use strict";
    this.taskOperation = p_function;
}

/**
    @param p_tasks: the list of tasks. Each task must have a taskOperation method.
    @param callback: a callback function, callback(boolean success, string errorMessage) will be called when all tasks finish.
*/
function SyncTaskList(p_tasks, p_callback) {
    "use strict";
    var v_tasks = p_tasks;
    var v_counter = -1;
    var v_finished = false;
    var v_success = true;
    var v_data = [];

    this.taskOperation = function() {
        if (!v_finished) {
            callback(true);
        }
    };

    function callback(ok, data) {
        if (ok && data != undefined) {
            v_data[v_counter] = data;
        }
        if (!ok) {
            v_success = false;
            v_data[v_counter] = data;
            p_callback(v_success, v_data);
        } else if (v_counter === v_tasks.length - 1) {
            v_finished = true;
            p_callback(v_success, v_data);
        } else {
            v_counter++;
            var task = v_tasks[v_counter];
            if (task.taskOperation != undefined) {
                task.taskOperation(callback);
            } else {
                if (window.console) console.error("No executable method found! " + Object.prototype.toString(task));
            }
        }
    }

    this.extend = function(p_tasks) {
        for (var i = 0; i < p_tasks.length; ++i) {
            v_tasks.push(p_tasks[i]);
        }
    };

    this.push = function(p_task) {
        v_tasks.push(p_task);
    };
}


/**
    @param p_tasks: the list of tasks. Each task must have a taskOperation method.
    @param callback: a callback function, callback(boolean success, string errorMessage) will be called when all tasks finish.
*/
function TaskList(p_tasks, p_callback) {
    "use strict";
    var v_tasks = p_tasks;
    var v_callback = p_callback;
    var v_counter = v_tasks.length;
    var v_finished = false;
    var v_success = true;
    var v_data = [];

    function CTaskObject(index) {
        var taskIndex = index;
        this.callback = function(ok, data) {
            v_data[taskIndex] = data;
            v_counter--;

            if (!ok) {
                v_success = false;
            }
            checkStatus();
        };
    }

    this.taskOperation = function() {
        checkStatus();
        if (!v_finished) {
            for (var i = 0; i < v_tasks.length; ++i) {
                if (v_tasks[i].taskOperation != undefined) {
                    v_tasks[i].taskOperation(new CTaskObject(i).callback);
                } else {
                    if (window.console) console.error("No executable method found! " + Function.prototype.toString(v_tasks[i]));
                }
            }
        }
    };

    function checkStatus() {
        if (v_counter === 0) {
            v_finished = true;
            if (v_callback)
                v_callback(v_success, v_data);
        }
    }

    this.extend = function(p_tasks) {
        for (var i = 0; i < p_tasks.length; ++i) {
            v_tasks.push(p_tasks[i]);
            ++v_counter;
        }
    };

    this.push = function(p_task) {
        v_tasks.push(p_task);
        ++v_counter;
    };
}

function JsImportTask(p_file, p_fileHandler) {
    "use strict";
    var v_file = p_file;
    var v_fileHandler = p_fileHandler;
    this.taskOperation = function(callback) {
        v_fileHandler.importJsFile(v_file, callback);
    };
}

function ListDirectoryTask(p_directory, p_fileHandler) {
    "use strict";
    /* path separator is / (like in the urls or the comment char) */
    var v_directory = p_directory;
    var v_fileHandler = p_fileHandler;
    this.taskOperation = function(callback) {
        function dirArrived(directories) {
            callback(true, directories);
        }
        v_fileHandler.getDirectory(v_directory, dirArrived);
    };
}

function JsonSaveTask(loader, name) {
    var v_loader = loader;
    var v_name = name;
    this.taskOperation = function(callback) {
        v_loader.save(v_name, callback);
    };
}

function FileSaveTask(loader, content, name) {
    var v_loader = loader;
    var v_content = content;
    var v_name = name;
    this.taskOperation = function(callback) {
        v_loader.save(v_content, v_name, callback);
    };
}

function JsImportTaskList(p_files, p_fileHandler, p_callback) {
    "use strict";
    var v_fileHandler = p_fileHandler;
    var tasks = [];
    for (var i = 0; i < p_files.length; ++i) {
        tasks.push(new JsImportTask(p_files[i], v_fileHandler));
    }
    var taskList = new TaskList(tasks, p_callback);
    this.taskOperation = function() {
        taskList.taskOperation();
    };
}

function MultipleDirectoryListTask(p_loactions, p_fileHandler) {
    var v_loactions = p_loactions;
    var v_fileHandler = p_fileHandler;

    this.taskOperation = function(callback) {
        function directoriesListed(ok, data) {
            var jsfiles = [];
            var cssfiles = [];
            var htmlfiles = [];

            for (var i = 0; i < data.length; ++i) {
                var files = data[i];
                for (var j = 0; j < files.length; ++j) {
                    var fileName = files[j].fileName;
                    if (fileName.endsWith(".js")) {
                        jsfiles.push(fileName);
                    } else if (fileName.endsWith(".css")) {
                        cssfiles.push(fileName);
                    } else if (fileName.endsWith(".html")) {
                        htmlfiles.push(fileName);
                    }
                }
            }

            callback(ok, {
                "jsfiles": jsfiles,
                "cssfiles": cssfiles,
                "htmlfiles": htmlfiles
            });
        }

        var tasks = [];
        for (var i = 0; i < v_loactions.length; ++i) {
            tasks.push(new ListDirectoryTask(v_loactions[i], v_fileHandler));
        }

        new TaskList(tasks, directoriesListed).taskOperation();
    }
}

function JsImportFromConfigTask(p_configPath, p_fileHandler) {
    var v_fileHandler = p_fileHandler;
    var v_configPath = p_configPath;
    var v_callback;

    function configLoaded(ok, config) {
        function imported(ok) {
            v_callback(ok, config.apiExtension);
        }

        if (ok && config.filesToInclude != undefined) {
            new JsImportTaskList(config.filesToInclude, v_fileHandler, imported).taskOperation();
        } else {
            v_callback(true, config.apiExtension);
        }
    }

    this.taskOperation = function(callback) {
        v_callback = callback;
        new JsonLoader(v_configPath, v_fileHandler).taskOperation(configLoaded);
    };
}