use core:io;
use core:lang;
use lang:bs:macro;
use parser;

// Get the Url for a named sub-package of this package.
Url resUrl(Str name) : on Compiler {
	unless (pkg = named{}.find(SimplePart(name), Scope()) as Package)
		throw InternalError("Failed to find the package ${name}");

	unless (url = pkg.url)
		throw InternalError("Failed to extract the path to the package ${pkg}.");

	return url;
}

// Helper to copy a list of files or directories.
void copyFiles(Url from, Url to, Str[] names) {
	for (name in names) {
		Url f = (from / name).updated();
		Url t = to / name;

		if (f.dir) {
			copyAllFiles(f, t);
		} else {
			copyFile(from / name, to / name);
		}
	}
}

// Copy all files in a directory to another directory.
void copyAllFiles(Url from, Url to) {
	to.createDir();
	for (c in from.children) {
		if (c.dir) {
			copyAllFiles(c, to / c.name);
		} else {
			copyFile(c, to / c.name);
		}
	}
}

// Helper to copy a single file.
void copyFile(Url from, Url to) {
	var src = from.read;
	var dst = to.write;

	Buffer tmp = buffer(4096);
	do {
		tmp.filled = 0;
		tmp = src.fill(tmp);
		dst.write(tmp);
	} while (tmp.full());

	src.close();
	dst.close();
}

// Replace markers (of the form <?...?>) in a string with whatever is in a hashtable of potential
// markers.
Str replaceMarkers(Str in, Str->Str replace) {
	StrBuf out;

	Str markerStart = "<?";
	Str markerEnd = "?>";

	var lastOut = in.begin;
	var nextSearch = in.begin;
	do {
		var start = in.find(markerStart, nextSearch);
		out << in.cut(lastOut, start);
		lastOut = start;

	} while (start < in.end) {
		nextSearch = start + markerStart.count;

		var end = in.find(markerEnd, nextSearch);
		if (end == in.end)
			continue;

		Str title = in.cut(start + markerStart.count, end);
		unless (r = replace.at(title))
			continue;

		// If nothing is before the marker on the line, indent it accordingly.
		// var indentStart = in.findLast('\n', start);
		// Bool useIndent = true;
		// for (var i = indentStart + 1; i != start; i++) {
		// 	if (i.v != ' ' & i.v != '\t') {
		// 		useIndent = false;
		// 		break;
		// 	}
		// }

		// if (useIndent) {
		// 	out.indentBy(in.cut(indentStart + 1, start));
		// 	out.indent();
		// }

		out << r;

		// if (useIndent) {
		// 	out.dedent();
		// }
		lastOut = end + markerEnd.count;
	}

	out.toS;
}
