const db = require('../database.js');

const TABLE_NAME = "accounts";

function AccountManager() {
}

AccountManager.prototype.fromGoogleIdAuth = function(id, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { authGoogleUserId: id }, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromFacebookIdAuth = function(id, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { authFacebookUserId: id }, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromSlackIdAuth = function(id, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { authSlackUserEmailAndTeam: id }, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromIrcPass = function(pass, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { authIrcPass: pass }, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromPhoneAccess = function(acc, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { permanentPhoneAccess: { like: "%," +acc +",%" }}, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromId = function(id, cb) {
    var self = this;
    db.database.queryFirst(TABLE_NAME, { id: id }, (err, result) => {
        cb(self.fromDb(result));
    });
};

AccountManager.prototype.fromDb = function(dbResult) {
    if (!dbResult)
        return null;
    return new Account(dbResult);
};

function Account(dbResult) {
    this.id;

    this.authGoogleUserId;
    this.authFacebookUserId;
    this.authSlackUserEmailAndTeam;
    this.authIrcPass;

    this.certificates;
    this.cguReadAndAccepted;
    this.services;
    this.dirty;

    if (dbResult) {
        this.id = dbResult.id;

        this.authSlackUserEmailAndTeam = dbResult.authSlackUserEmailAndTeam;
        this.authGoogleUserId = dbResult.authGoogleUserId;
        this.authFacebookUserId = dbResult.authFacebookUserId;
        this.authIrcPass = dbResult.authIrcPass;

        this.certificates = dbResult.certificates;
        this.cguReadAndAccepted = !!dbResult.cguReadAndAccepted;
        this.services = JSON.parse(dbResult.services);
        this.permanentPhoneAccess = dbResult.permanentPhoneAccess.split(',').filter(token => token.length);
        this.dirty = false;
    } else {
        this.id = null;

        this.authSlackUserEmailAndTeam = null;
        this.authGoogleUserId = null;
        this.authFacebookUserId = null;
        this.authIrcPass = null;

        this.createCertificate();
        this.cguReadAndAccepted = false;
        this.permanentPhoneAccess = [];
        this.services = [];
        this.dirty = true;
    }
}

Account.prototype.toDb = function() {
    return {
        authGoogleUserId: this.authGoogleUserId
        ,authFacebookUserId: this.authFacebookUserId
        ,authSlackUserEmailAndTeam: this.authSlackUserEmailAndTeam
        ,authIrcPass: this.authIrcPass
        ,certificates: this.certificates
        ,cguReadAndAccepted: this.cguReadAndAccepted ? 1 : 0
        ,services: JSON.stringify(this.services)
        ,permanentPhoneAccess: ',' +this.permanentPhoneAccess.join(',') +','
    };
};

Account.prototype.createCertificate = function() {
    //TODO create certificate
    this.certificates = null;
};

Account.prototype.generateIrcPass = function() {
    // FIXME secure token generator
    this.edit();
    this.authIrcPass = "test";
    return this;
};

Account.prototype.generatePermanentPhoneAccess = function() {
    let token = "465465";
    this.edit();
    this.permanentPhoneAccess.push(token);
    return token;
};

Account.prototype.addService = function(serviceType, serviceName, serviceId, oauthParam) {
    this.services.push([serviceType, serviceName, serviceId, oauthParam]);
};

Account.prototype.getServices = function() {
    var services = {};
    this.services.forEach((i) => {
        services[i[2]] = {
            type: i[0],
            name: i[1],
            oauthParam: i[3]
        };
    });
    return services;
};

Account.prototype.edit = function() {
    this.dirty = true;
    return this;
};

AccountManager.prototype.createAccount = function() {
    return new Account();
};

AccountManager.prototype.save = function(account, cb) {
    if (!account.id) {
        // insert and save id
        var data = account.toDb();
        data.id = null;
        db.database.insert(TABLE_NAME, data, (newId) => {
            account.id = newId;
            account.dirty = false;
            if (cb) cb(account);
        });
    } else if (account.dirty) {
        // update
        db.database.update(TABLE_NAME, account.id, account.toDb(), () => {
            account.dirty = false;
            if (cb) cb(account);
        });
    } else {
        if (cb) cb(account);
    }
};

module.exports.accountManager = new AccountManager();

module.exports.updateTable = function(dbObject, currentVersion, cb) {
    if (!currentVersion) {
        console.info("Creating table " +TABLE_NAME);
        dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
            +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
            +"`authGoogleUserId` STRING UNIQUE,"
            +"`authFacebookUserId` STRING UNIQUE,"
            +"`authSlackUserEmailAndTeam` STRING UNIQUE,"
            +"`certificates` STRING,"
            +"`cguReadAndAccepted` BOOLEAN NOT NULL DEFAULT FALSE,"
            +"`services` STRING NOT NULL"
            +')', cb);
    } else if (currentVersion === 1) {
        console.info("Updating table " +TABLE_NAME);
        dbObject.run('ALTER TABLE ' +TABLE_NAME +' ADD COLUMN `authIrcPass` STRING;'+
            'CREATE UNIQUE INDEX authIrcPassUniq ON ' +TABLE_NAME +'(authIrcPass)', cb);
    } else if (currentVersion === 2) {
        console.info("Updating table " +TABLE_NAME);
        dbObject.run('ALTER TABLE `' +TABLE_NAME +'` ADD COLUMN `permanentPhoneAccess` STRING NOT NULL DEFAULT "";', cb);
    } else {
        cb(null);
    }
};

