async function query(sql, params) {
	let results = [];
	await ssb.sqlAsync(sql, params, function (row) {
		results.push(row);
	});
	return results;
}

function guess_content_type(name) {
	if (name.endsWith('.html')) {
		return 'text/html; charset=UTF-8';
	} else if (name.endsWith('.js') || name.endsWith('.mjs')) {
		return 'text/javascript; charset=UTF-8';
	} else if (name.endsWith('.css')) {
		return 'text/stylesheet; charset=UTF-8';
	} else {
		return 'application/binary';
	}
}

async function main() {
	let path = request.path.replaceAll(/(%[0-9a-fA-F]{2})/g, (x) =>
		String.fromCharCode(parseInt(x.substring(1), 16))
	);
	let content_type = guess_content_type(request.path);
	let blob;
	let last_id;

	let match = path.match(/.*?\/?(%.{44}\.sha256)(?:\/)?(.*)$/);
	if (match) {
		let root = await query(
			`
			SELECT root.content ->> 'root' AS root
			FROM messages site
			JOIN messages root
			ON site.id = ? AND root.author = site.author AND root.content ->> 'site' = site.id
			ORDER BY root.sequence DESC LIMIT 1
		`,
			[match[1]]
		);
		let root_id = root[0]?.root;
		last_id = root_id;
		blob = await ssb.blobGet(root_id);
		try {
			for (let part of match[2]?.split('/')) {
				let dir = JSON.parse(utf8Decode(blob));
				last_id = dir?.links[part];
				blob = await ssb.blobGet(dir?.links[part]);
				content_type = guess_content_type(part);
			}
		} catch {}
	}

	respond({
		status_code: blob ? 200 : 404,
		data: blob ? utf8Decode(blob) : `${last_id ?? path} not found`,
		content_type: content_type,
	});
}

main().catch(function (e) {
	respond({
		status_code: 200,
		data: `${e.message}\n${e.stack}`,
		content_type: 'text/plain',
	});
});
