/*
 * 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.
 */
const request = require('request')
const fs = require('fs')
const path = require('path')
const logger = require('./consoleLogger');

const listEndpoint = "/bin/cpm/package.list.json";
const uploadEndpoint = "/bin/cpm/package.upload.json";
const deleteEndpoint = "/bin/cpm/package.delete.json";
const installEndpoint = "/bin/cpm/package.install.json";
const uninstallEndpoint = "/bin/cpm/package.uninstall.json";

const check = (url, username, password, callback) => {
    let serviceURL = url + '/bin/cpm/package.json';
    logger.debug('Checking Composum Package Manager.');
    logger.debug('Service call: ', serviceURL);
    request.get({ url: serviceURL }, (error, response, body) => {
        if (response && response.statusCode === 200) {
            callback(true);
        } else {
            callback(false)
        }

    }).auth(username, password);
}

const list = (url, username, password, maxRetry) => {
    logger.log('Listing packages on', url);
    listPackages(url, username, password, '', maxRetry);
}

const upload = (url, username, password, packagePath, install, maxRetry) => {
    logger.log('Uploading package', packagePath, 'on', url);

    let serviceURL = url + uploadEndpoint + "?force=true";
    let post = callPostService({serviceURL, username, password, maxRetry}, (error, json) => {
        if(error) {
            logger.error('Unable to upload package', packagePath);
            logger.error(error);
            process.exit(1);
        } else {
            logger.log(json.status)
            logger.debug(JSON.stringify(json));

            if(install) {
                logger.info('installing', json.path);
                installPackage(url, username, password, json.path, maxRetry);
            }
        }
    });

    post.form().append('file', fs.createReadStream(packagePath));

    logger.debug(JSON.stringify(post.toJSON()));
}

const deletePackage = (url, username, password, package, maxRetry) => {
    logger.log('Deleting package', package, 'on', url);

    let serviceURL = url + deleteEndpoint + package;
    let req = callService({serviceURL, method: 'DELETE', username, password, maxRetry}, (error, json) => {
        if(error) {
            logger.error('Unable to delete package', package);
            logger.error(error);
            process.exit(1);
        } else {
            logger.log(json.status);
            logger.debug(JSON.stringify(json));
        }
    });

    logger.debug(JSON.stringify(req.toJSON()));
}

const install = (url, username, password, package, maxRetry) => {
    logger.log('Installing package', package, 'on', url);

    let post = postJob({url, username, password, package, maxRetry}, 'install', (error, result) => {
        if(error) {
            logger.error('Unable to uninstall package', package);
            logger.error(error);
            process.exit(1);
        } 
    });
}

const uninstall = (url, username, password, package, maxRetry) => {
    logger.log('Uninstalling package', package, 'on', url);

    let post = postJob({url, username, password, package, maxRetry}, 'uninstall', (error, result) => {
        if(error) {
            logger.error('Unable to uninstall package', package);
            logger.error(error);
            process.exit(1);
        } else {
            if(result && (typeof(result) === 'string') && result.startsWith('Unable')) {
                logger.error(result);
                process.exit(1);
            }
        }
    });
}

const build = (url, username, password, package, maxRetry) => {
    logger.log('Building package', package, 'on', url);

    let post = postJob({url, username, password, package, maxRetry}, 'assemble', (error, result) => {
        if(error) {
            logger.error('Unable to build package', package);
            logger.error(error);
            process.exit(1);
        } else {
            if(result && (typeof(result) === 'string') && result.startsWith('Unable')) {
                logger.error(result);
                process.exit(1);
            }
        }
    });
}

const download = (url, username, password, destination, package, maxRetry) => {
    logger.log('Downloading package', package, 'from', url, 'to', destination);
    let serviceURL = url + "/bin/cpm/package.download.zip" + package;
    downloadPackage({url, username, password, destination, package, maxRetry});
}

const getName = () => {
    return 'Composum Package Manager';
}

function downloadPackage(data) {
    if(data.filePath) {
        data.serviceURL = data.url + "/bin/cpm/package.download.zip" + data.package;
        callGetService(data, (error, response) => {
            if(error) {
                logger.error("Unable to download package.");
                process.exit(1);
            } else {
                if(fs.existsSync(data.filePath)) {
                    var stats = fs.statSync(data.filePath);
                    logger.log("Package downloaded.");
                    logger.log(stats.size + " " + data.filePath);
                }
            }
        }, true).pipe(fs.createWriteStream(data.filePath));;
    } else {
        data.serviceURL = data.url + listEndpoint;
        let req = callGetService(data, (error, response) => {
            if(error) {
                logger.error("Unable to download package.");
                process.exit(1);
            } else {
                var packages = response.children ? response.children : response;
                for (var i = 0; i < packages.length; i++) {
                    if(packages[i].type === 'package' && isPackage(packages[i], data.package)) {
                        let fileName = packages[i].file;
                        let filePath = path.join(data.destination, fileName);
                        data.filePath = filePath;
                        data.package = packages[i].path;
                        downloadPackage(data);
                        return;
                    }
                }

                logger.error("Unable to download package. Package " + data.package + " is not found on server.");
            }
        }, false);

        logger.debug("Request: ", JSON.stringify(req.toJSON(), undefined, '   '));
    }
}

function isPackage(packJson, name) {
    if(packJson.id === name || packJson.name === name || packJson.path === name) {
        return true;
    } else {
        return packJson.definition.name === name;
    }
}

function listPackages(url, username, password, path, maxRetry) {
    var serviceURL = url + listEndpoint + path;
    
    let req = callGetService({serviceURL, username, password, maxRetry}, (error, json) => {
        if(error) {
            logger.error("Unable to list packages.");
            logger.error(error);
            process.exit(1);
        } else {
            var packages = json.children ? json.children : json;
            displayPackages(url, username, password, packages);
        }
    }); 

    logger.debug(JSON.stringify(req.toJSON()));
}

function displayPackages(url, username, password, packages) {
    for (var i = 0; i < packages.length; i++) {
        if(packages[i].type === 'package') {
            logger.log('name=' + packages[i].definition.name +
                ' group=' + packages[i].definition.group +
                ' version=' + packages[i].definition.version +
                ' path=' + packages[i].id);
        } else if(packages[i].type === 'folder') {
            // This is not needed on Sling11 as list service returns complete list of packages.
            listPackages(url, username, password, packages[i].path);
        }
    }
}

function postJob(data, operation, callback) {
    data.serviceURL = data.url + '/bin/cpm/core/jobcontrol.job.json';
    let post = callPostService(data, (error, json) => {
        if(json && json['slingevent:eventId']) {
            setTimeout(() => {
                getJobOutput(data.url, data.username, data.password, json['slingevent:eventId'], callback)
            },100);
        } else {
            callback(error, json); 
        }
    });

    var form = post.form();
    form.append('event.job.topic', 'com/composum/sling/core/pckgmgr/PackageJobExecutor');
    form.append('_charset_', 'UTF-8');
    form.append('operation', operation);
    form.append('reference', data.package);

    return post;
}

function callGetService(data, callback, isDownload=false) {
    data.method = "GET";
    return callService(data, callback, isDownload);
}

function callPostService(data, callback) {
    data.method = "POST";
    var post = callService(data, callback);
    logger.debug('POST:', JSON.stringify(post.toJSON(), undefined, '   '));
    return post;
}

function callService(data, callback, isDownload=false) {
    if(data.retryCount === undefined) {
        data.retryCount = 0;
        if(data.maxRetry === undefined) {
            data.maxRetry = 10;
        }
    }

    logger.debug(data.retryCount + '. Service call: ', data.serviceURL);

    let req = request({ url: data.serviceURL, method: data.method }, (error, response, body) => {
        var statusCodeLine = (response === undefined) ? "" : "Response: " + response.statusCode + " : " + response.statusMessage;
        logger.debug(statusCodeLine);

        if (error) {
            if(data.retryCount < data.maxRetry) {
                data.retryCount++;
                callService(data, callback);
            } else  { 
                logger.error(error);
                callback(error + " " + statusCodeLine, undefined); 
            }

            return;
        }

        if (response && response.statusCode === 200) {
            if (body) {
                if(isDownload) {
                    callback(undefined, response);
                } else {
                    var json = JSON.parse(body);
                    logger.debug('Response:', JSON.stringify(json, undefined, '   '));
                    callback(undefined, json);
                }
                return;
            } else {
                logger.debug("Respons has no body.");
            }
        }

        if(data.retryCount < data.maxRetry) {
            data.retryCount++;
            callService(data, callback);
        } else  { 
            callback("Error calling service " + data.serviceURL, undefined);
        }

        return;
    }).auth(data.username, data.password);
    return req;
}

function getJobOutput(url, username, password, eventId, callback, jobState) {
    var requestData = {url: url + "/bin/cpm/core/jobcontrol.outfile.txt/" + eventId};
    if(jobState === undefined || jobState === "ACTIVE" || jobState === "QUEUED") {
        requestData.url = url + "/bin/cpm/core/jobcontrol.job.json/" + eventId;
    } 

    request.get(requestData, (error, response, body) => {
        var statusCodeLine = (response === undefined) ? "" : "Response: " + response.statusCode + " : " + response.statusMessage;
        logger.debug(statusCodeLine);

        if(error) {
            logger.error(error);
        } else if(body) {
            if(body.trim().startsWith("{")) {
                var json = JSON.parse(body);
                logger.debug('Response:', JSON.stringify(json, undefined, '   '));
                if(json["jobState"]) {
                    setTimeout(()=>{
                        getJobOutput(url, username, password, eventId, callback, json["jobState"]);
                    }, 100);
                    return;
                }
            } 
            
            logger.log(body.trim());
        } else if (response && response.statusCode != 200) {
            if(callback) {
                callback('Package manager job service failed. '+statusCodeLine, undefined);
            } else {
                logger.error('Package manager job service failed.', statusCodeLine);
                process.exit(1);
            }
        }

        if(callback) {
            callback(error, body); 
        } 

    }).auth(username, password);
}

module.exports = {
    check,
    list,
    upload,
    deletePackage,
    install,
    uninstall,
    build,
    download,
    getName
}

