const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');

const basename = path.basename(module.filename);
const env = process.env.NODE_ENV || 'development';
const config = require('config');

const db = {};

const sequelize = new Sequelize(config.get('database_url'));

fs.readdirSync(__dirname)
    .filter((file) => {
        return (
            file.indexOf('.') !== 0 &&
            file !== basename &&
            file.slice(-3) === '.js'
        );
    })
    .forEach((file) => {
        const model = sequelize.import(path.join(__dirname, file));
        db[model.name] = model;
    });

Object.keys(db).forEach((modelName) => {
    if (db[modelName].associate) {
        db[modelName].associate(db);
    }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

if (env === 'development') {
    // in dev, sync all table schema automatically for convenience
    sequelize.sync();
}

function esc(value, max_length = 256) {
    if (!value) return '';
    if (typeof value === 'number') return value;
    if (typeof value === 'boolean') return value;
    if (typeof value !== 'string') return '(object)';
    const res = value
        .substring(0, max_length - max_length * 0.2)
        .replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, (char) => {
            switch (char) {
                case '\0':
                    return '\\0';
                case '\x08':
                    return '\\b';
                case '\x09':
                    return '\\t';
                case '\x1a':
                    return '\\z';
                case '\n':
                    return '\\n';
                case '\r':
                    return '\\r';
                // case '\'':
                // case "'":
                // case '"':
                // case '\\':
                // case '%':
                //     return '\\' + char; // prepends a backslash to backslash, percent, and double/single quotes
            }
            return '-';
        });
    return res.length < max_length ? res : '-';
}

db.esc = esc;

db.escAttrs = function (attrs) {
    const res = {};
    Object.keys(attrs).forEach((key) => (res[key] = esc(attrs[key])));
    return res;
};

module.exports = db;
