import { Database } from '@db/sqlite';

export function migrate(db: Database) {
	const migrationDirEntries = Deno.readDirSync(import.meta.dirname + '/migrations');
	const migrations = [];
	for (const migration of migrationDirEntries) {
		const content = Deno.readTextFileSync(
			import.meta.dirname + `/migrations/${migration.name}`,
		);
		migrations.push([migration.name, content]);
	}

	migrations.sort((a, b) => a[0].localeCompare(b[0]));

	const schemaVersionDesired = migrations.length;
	const { user_version: schemaVersionDb } = db.prepare('pragma user_version').get<
		{ user_version: number }
	>()!;

	let applyMigrations = false;
	if (schemaVersionDb != schemaVersionDesired) {
		console.error(
			`The database schema is on ${schemaVersionDb}, but the desired version is ${schemaVersionDesired}`,
		);
		applyMigrations = confirm('Apply migrations?');
	}

	if (!applyMigrations) {
		return;
	}

	const migrationsToApply = migrations.slice(schemaVersionDb);
	const txn = db.transaction(() => {
		for (const [name, migration] of migrationsToApply) {
			try {
				db.exec(migration);
			} catch (e) {
				throw new Error(`While running migration ${name}`, { cause: e });
			}
		}

		db.exec(`pragma user_version = ${schemaVersionDesired}`);
	});

	txn.immediate();
}
