const fs = require('fs');
const node_ssh = require('node-ssh');
const sdk = require('matrix-js-sdk');
const yaml = require('js-yaml');

const config = yaml.safeLoad(fs.readFileSync('config.yaml'));
const matrixclient = sdk.createClient({
    baseUrl: config.matrix.baseurl,
    accessToken: config.matrix.accesstoken,
    userId: config.matrix.userid
});
const ssh = new node_ssh();

// Autojoin for the bot (keep commented out when not needed to prevent abuse)
/*matrixclient.on('RoomMember.membership', function(event, member) {
    if(member.membership === 'invite' && member.userId === userid) {
        matrixclient.joinRoom(member.roomId).done(function() {
            console.log('Auto-joined %s', member.roomId);
        });
    }
});*/

//captures unhandled rejections for easier debugging 
process.on('unhandledRejection', (reason) => {
    console.log('Reason: ' + reason);
});

function remoterun(command, args) {
    return new Promise(function(resolve, reject) {
        ssh.connect({
            host: config.ssh.host,
            username: config.ssh.user,
            privateKey: config.ssh.key
        })
        .then(function(){
            ssh.execCommand('/usr/bin/sudo -- ' + command, {cwd: config.infrastructure})
            .then(function(result) {
                if(result.code === 0) {
                    resolve(result);
                } else {
                    reject(result);
                }
            }, function(result) {
                reject(result);
            })
        }, function(result) {
            reject(result)
        });
    });
};


const commands = {};

commands['rebuild'] = {};
commands['rebuild'].regex = /^!rebuild ([a-zA-Z0-9\-]*)$/;
commands['rebuild'].usage = '!rebuild <container>';
commands['rebuild'].exec = function(args, room, event) {
    const container = args[1];

    matrixclient.sendNotice(room.roomId, 'rebuilding container ' + container);

    remoterun('./rebuild.sh ' + container);
    .then(function(result) {
        matrixclient.sendNotice(room.roomId, event.sender.userId + '\nrebuilt container ' + container);
    }, function(result) {
        matrixclient.sendNotice(room.roomId, event.sender.userId + '\nrebuild of container ' + container + ' failed.\ncode: ' + result.code + '\nstdout: \n```\n' + result.stdout + '```\nstderr: \n```\n' + result.stderr + '\n```');
    });

};


matrixclient.on('Room.timeline', function(event, room, resettimeline) {
    if(resettimeline) {
        return;
    }
    if(event.getType() !== 'm.room.message') {
        return;
    }

    let body = event.getContent().body;

    let project = body.match(/^\!([a-zA-Z]*)/);
    if(project === null) {
        return;
    }
    project = project[1];

    if(commands[project] !== undefined) {
        const command = commands[project];

        const args = body.match(command.regex);
        if(args === null) {
            matrixclient.sendNotice(room.roomId, 'usage: ' + command.usage);
            return;
        }

        command.exec(args, room, event);
    }
});



matrixclient.startClient();