/*
	Licensed Material - Property of IBM

	(C) Copyright 2015 IBM Corp.

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


'use strict';

var Docker = require('dockerode');
var waitOn = require('wait-on');
var log = require('npmlog');
var Q = require('q');
var consts = require('./constants');

log.level = global.MDO_CLI_LOG_LEVEL ? global.MDO_CLI_LOG_LEVEL : log.level;

var docker = new Docker();

module.exports.startContainer = function (imageName, profile) {
    var deferred = Q.defer();
    var found = false;
    docker.listContainers({ all: true }, function (err, containers) {
        if (err) {
            deferred.reject(err);
        } else {
            for (let index = 0; index < containers.length; index++) {
                let containerInfo = containers[index];
                if (containerInfo.Image == imageName) {
                    log.verbose(consts.LOG_PREFIX, 'Image: ' + containerInfo.Image);
                    log.verbose(consts.LOG_PREFIX, 'Status: ' + containerInfo.State);                    
                    var container = docker.getContainer(containerInfo.Id);
                    if (containerInfo.State != "running") {
                        container.remove().then(function() {
                            internalStartService(imageName, profile).then(function() {
                                deferred.resolve({
                                    url:`${profile.protocol}://${profile.ipAddress}:${profile.port}`, 
                                    user: `${profile.login}`,
                                    password: `${profile.password}`
                                });
                            }).catch(function(err) {
                                deferred.reject(err);
                            });
                        }).catch(function(err) {
                            deferred.reject(err);
                        });
                    } else {
                        deferred.resolve({
                            url:`${profile.protocol}://${profile.ipAddress}:${profile.port}`, 
                            user: `${profile.login}`,
                            password: `${profile.password}`
                        });
                    } 
                    found = true;
                    break;  
                }                       
            }
            if (!found) {
                internalStartService(imageName, profile).then(function() {
                    deferred.resolve({
                        url:`${profile.protocol}://${profile.ipAddress}:${profile.port}`, 
                        user: `${profile.login}`,
                        password: `${profile.password}`
                    });
                }).catch(function(err) {
                    deferred.reject(err);
                });
            }            
        }
    }); 
   
    return deferred.promise;
}

function internalStartService(imageName, profile) {
    var deferred = Q.defer();
    docker.createContainer({
        Image: imageName,
        name: 'mfp-server-all',
        ExposedPorts: {
          '9080/tcp': {}
        },
        Env: [ "MFPF_ANALYTICS_PROTOCOL=http", `ANALYTICS_SVC_NAME=${profile.ipAddress}`, 
                "ANALYTICS_PORT=9080", "MFPF_SERVER_PROTOCOL=http",
                `ADMIN_HOST=${profile.ipAddress}`, "MFPF_SERVER_PORT=9080",
                `RUNTIME_SVC_NAME=${profile.ipAddress}`, `MFPF_ANALYTICS_RECVR_HOST=${profile.ipAddress}:9080`],
        HostConfig: {
          PortBindings: {
            '9080/tcp': [
              {
                HostPort: '9080'
              }
            ]
          }
        }
    }).then(function (container) {
        return container.start();
    }).then(function() {     
        var opts = {
            resources: [
                'http-get://localhost:9080/mfpadmin/ping',
                'http-get://localhost:9080/mfpadmin/management-apis/2.0/runtimes/mfp',
            ],
            delay: 2000, // initial delay in ms, default 0
            interval: 1000, // poll interval in ms, default 250ms
            timeout: 180000, // setting to 3 mins, default Infinity
            tcpTimeout: 1000, // tcp timeout in ms, default 300ms
            window: 1000, // stabilization time in ms, default 750ms
            strictSSL: false,
            auth: {
                user: 'admin',
                pass: 'admin'
            },
        };

        // return waitPort({'localhost', port:9080})
        return waitOn(opts);
    }).then(function () {
        deferred.resolve();
    }).catch(function (err) {
        deferred.reject(err);
    });    

    return deferred.promise;   
}


module.exports.stopContainer = function (imageName) {
    var deferred = Q.defer();
    var found = false;

    docker.listContainers({ all: true }, function (err, containers) {
        if (err) {
            deferred.reject(err);
        } else {
            for (let index = 0; index < containers.length; index++) {
                let containerInfo = containers[index];
                if (containerInfo.Image == imageName) {
                    log.verbose(consts.LOG_PREFIX, 'Image: ' + containerInfo.Image);
                    log.verbose(consts.LOG_PREFIX, 'Status: ' + containerInfo.State);
                    var container = docker.getContainer(containerInfo.Id);
                    if (containerInfo.State != "running") {
                        container.remove().then(function() {
                            deferred.resolve();
                        }).catch(function(err) {
                            deferred.reject(err);
                        });
                    } else {
                        container.stop().then(function() {
                            container.remove().then(function() {
                                deferred.resolve();
                            }).catch(function(err) {
                                deferred.reject(err);
                            });
                        }).catch(function(err) {
                            deferred.reject(err);
                        });                        
                    } 
                    found = true;
                    break;  
                }                         
            }
            if (!found) {
                deferred.resolve();
            }            
        }
    }); 
   
    return deferred.promise;
}

module.exports.pullImage = function(imageName) {
    var deferred = Q.defer();

    docker.pull(imageName, function (error, stream) {
        if (error) {
            deferred.reject(error);
        } else {
            docker.modem.followProgress(stream, function (streamErr) {
                if (streamErr) {
                    deferred.reject(streamErr);
                } else {
                    deferred.resolve();
                }
            }, function (event) {
                log.verbose(consts.LOG_PREFIX, 'Pull status: ' + event);
            });
        }
    });

    return deferred.promise;
}
