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

let db;

async function conectarDB() {
	if (db) return db;
	const dbfile = process.env.SQLITE_FILE || "notas.sqlite3";
	await new Promise((resolve, reject) => {
		db = new sqlite3.Database(dbfile,
			sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
			err => {
				if (err) return reject(err);
				resolve(db);
			});
		});
	return db;
}

export default class AlmacenNotasSQL3 extends AlmacenNotasAbs {
	async cerrar() {
		const _db = db;
		db = undefined;
		return _db ?
			new Promise((resolve, reject) => {
				_db.close(err => {
					if (err) reject(err);
					else resolve();
				});
			}) : undefined;
	}

	async update(clave, titulo, cuerpo) {
		const db = await conectarDB();
		const nota = new Nota(clave, titulo, cuerpo);
		await new Promise((resolve, reject) => {
			db.run("UPDATE notas " +
				"SET titulo = ?, cuerpo = ? WHERE clave = ?",
				[titulo, cuerpo, clave ], err => {
					if (err) return reject(err);
					resolve(nota);
				});
		});
		return nota;
	}
        async create(clave, titulo, cuerpo) {
                const db = await conectarDB();
                const nota = new Nota(clave, titulo, cuerpo);
                await new Promise((resolve, reject) => {
                        db.run("INSERT INTO notas (clave, titulo, cuerpo) " +
                                "VALUES (?, ?, ?);", [clave, titulo, cuerpo],
                                err => {
                                        if (err) return reject(err);
                                        resolve(nota);
				});
                });
                return nota;
        }

	async read(clave) {
		const db = await conectarDB();
		const nota = await new Promise((resolve, reject) => {
			db.get("SELECT * FROM notas where clave = ?",
			  [clave], (err, fila) => {
				if (err) return reject(err);
				const nota = new Nota(fila.clave, fila.titulo,
						fila.cuerpo);
				resolve(nota);
			});
		});
		return nota;
	}

	async delete(clave) {
		const db = await conectarDB();
		return await new Promise((resolve, reject) => {
			db.run("DELETE FROM notas WHERE clave = ?",
				[clave], err => {
					if (err) return reject(err);
					resolve();
			});
		});
	}

	async listarClaves() {
		const db = await conectarDB();
		const clavez = await new Promise((resolve, reject) => {
			const clavez = [];
			db.all("SELECT clave FROM notas", (err, filas) => {
				if (err) return reject(err);
				resolve(filas.map(fila => {
					return fila.clave;
				}));
			});
		});
		return clavez;
	}

	async contar() {
		const db = await conectarDB();
		const contar = await new Promise((resolve, reject) => {
			db.get("SELECT count(clave) as contar from notas",
				(err, fila) => {
					if (err) return reject(err);
					resolve(fila.contar);
			});
		});
		return contar;
	}
}
