import util from 'util';
import { Nota, AlmacenNotasAbs } from './Notas.mjs';
import level from 'level';
import { default as DBG } from 'debug';
const debug = DBG('notas:notas-level');
const error = DBG('notas:error-level');

let db;

async function conectarDB() {
	if (typeof db !== 'undefined' || db) return db;
	db = await level(
		process.env.LEVELDB_LOCATION || 'notas.level', {
			createIfMissing: true,
			valueEncoding: "json"
		});
	return db;
}

export default class AlmacenNotasLevel extends AlmacenNotasAbs {
	async cerrar() {
		const _db = db;
		db = undefined;
		return _db ? _db.close() : undefined;
	}

	async update(clave, titulo, cuerpo) {
		return crupdate(clave, titulo, cuerpo);
	}

	async create(clave, titulo, cuerpo) {
		return crupdate(clave, titulo, cuerpo);
	}

	async read(clave) {
		const db = await conectarDB();
		const nota = Nota.desdeJSON(await db.get(clave));
		return nota;
	}

	async delete(clave) {
		const db=await conectarDB();
		await db.del(clave);
	}

	async listarClaves() {
		const db = await conectarDB();
		const clavez = [];
		await new Promise((resolve, reject) => {
			db.createKeyStream()
			.on('data', data => clavez.push(data))
			.on('error', err => reject(err))
			.on('end', () => resolve(clavez));
		});
		return clavez;
	}

	async contar() {
		const db = await conectarDB();
		var total = 0;
		await new Promise((resolve, reject) => {
			db.createKeyStream()
			.on('data', data => total++)
			.on('error', err => reject(err))
			.on('end', () => resolve(total));
		});
		return total;
	}
}

async function crupdate(clave, titulo, cuerpo) {
	const db = await conectarDB();
	const nota = new Nota(clave, titulo, cuerpo);
	await db.put(clave, nota.JSON);
	return nota;
}
