/*
 * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#include <studio/context.hpp>

namespace studio {

void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs) noexcept {
	ox::String path = std::move(filePath);
	if (keel::isUuidUrl(path)) {
		auto const [p, err] = keel::uuidUrlToPath(keelCtx(ctx), path);
		if (err) {
			return;
		}
		path = p;
	}
	//if (
	//	auto const [np, err] = ctx.navStack.back();
	//	!err && np->filePath == path && np->navArgs == navArgs.view()) {
	//	return;
	//}
	ctx.navStack.resize(ctx.navIdx + 1);
	ctx.navStack.emplace_back(ox::String{path}, ox::String{navArgs.view()});
	try {
		ctx.navCallback(std::move(path), std::move(navArgs));
	} catch (std::exception const &e) {
		oxErrf("Nav error: {}", e.what());
		oxAssert(false, "Nav error");
	}
}

void navigateBack(Context &ctx) noexcept {
	if (!ctx.navIdx) {
		return;
	}
	--ctx.navIdx;
	while (ctx.navIdx < ctx.navStack.size() && ctx.navIdx) {
		auto const i = ctx.navIdx - 1;
		auto const &n = ctx.navStack[i];
		if (!ctx.project->exists(n.filePath)) {
			std::ignore = ctx.navStack.erase(i);
			--ctx.navIdx;
			continue;
		}
		try {
			ctx.navCallback(n.filePath, n.navArgs);
		} catch (std::exception const &e) {
			oxAssert(ctx.navCallback != nullptr, "navCallback is null");
			oxErrf("navigateForward failed: {}", e.what());
		}
		break;
	}
}

void navigateForward(Context &ctx) noexcept {
	auto const nextIdx = ctx.navIdx + 1;
	while (nextIdx < ctx.navStack.size()) {
		auto const &n = ctx.navStack[nextIdx];
		try {
			ctx.navCallback(n.filePath, n.navArgs);
		} catch (std::exception const &e) {
			oxAssert(ctx.navCallback != nullptr, "navCallback is null");
			oxErrf("navigateForward failed: {}", e.what());
		}
		if (!ctx.project->exists(n.filePath)) {
			std::ignore = ctx.navStack.erase(nextIdx);
			continue;
		}
		++ctx.navIdx;
		break;
	}
}

}