const fs = require('fs')
const crypto = require('crypto')
const sqlite3 = require('better-sqlite3')

const db = sqlite3(`./data/db.sqlite`)
db.pragma('journal_mode = WAL')
db.pragma('foreign_keys = on')

db.exec(fs.readFileSync('./data/init.sql', 'utf8'))

db.function('generate_key', (id, time) => {
	return [
		'KEY',
		Buffer.from(time + '').toString('base64'),	
		crypto.createHash('md5').update(`sa${time}-${id}lt`).digest('hex')
	].join('-')
})

process.on('exit', () => db.close())
process.on('SIGHUP', () => process.exit(128 + 1))
process.on('SIGINT', () => process.exit(128 + 2))
process.on('SIGTERM', () => process.exit(128 + 15))

db.prepareUpdate = function (table, columns, data, where) {
	const dataColumns = columns.filter(col => col in data)
	if (dataColumns.length == 0)
		throw Error('SQLite Error: No data to update')

	return db.prepare(`update "${table}" ` +
		`set ` + dataColumns.map(col => `"${col}" = :${col}`).join(', ') + 
		` where ` + where.map(col => `"${col}" = :${col}`).join(' and ')) 		
}

db.prepareUpsert = function (table, columns, data, where) {
	const dataColumns = columns.filter(col => col in data)
	if (dataColumns.length == 0)
		throw Error('SQLite Error: No data to update')

	return db.prepare(
		`insert into "${table}" (` + [...dataColumns, ...where].join(', ') + `) values (:` + [...dataColumns, ...where].join(', :') +
		`) on conflict (` + where.join(',')  + `) do update ` +
		`set ` + dataColumns.map(col => `"${col}" = :${col}`).join(', ') + 
		` where ` + where.map(col => `"${col}" = :${col}`).join(' and '))		
}

module.exports = db