












ll := import("@platforma-sdk/workflow-tengo:ll")



columnEntry := func(columnId, qualifications) {
	entry := { entry: { type: "column", column: columnId } }
	if !is_undefined(qualifications) && len(qualifications) > 0 {
		entry.qualifications = qualifications
	}
	return entry
}

linkerJoinEntry := func(linkerId, secondary, qualifications) {
	entry := {
		entry: {
			type: "linkerJoin",
			linker: { column: linkerId },
			secondary: secondary
		}
	}
	if !is_undefined(qualifications) && len(qualifications) > 0 {
		entry.qualifications = qualifications
	}
	return entry
}

innerJoinEntry := func(entries, qualifications) {
	entry := { entry: { type: "innerJoin", entries: entries } }
	if !is_undefined(qualifications) && len(qualifications) > 0 {
		entry.qualifications = qualifications
	}
	return entry
}

wrapLinker := func(currentEntry, linkerId) {
	return linkerJoinEntry(linkerId, [currentEntry], [])
}

wrapFilter := func(currentEntry, filterId) {
	return innerJoinEntry([currentEntry, columnEntry(filterId, [])], [])
}

stepColumnId := func(step) {
	if step.type == "linker" {
		ll.assert(!is_undefined(step.linker), "linker step missing 'linker' field")
		ll.assert(!is_undefined(step.linker.columnId),
			"linker step's linker missing 'columnId' field")
		return step.linker.columnId
	}
	if step.type == "filter" {
		ll.assert(!is_undefined(step.filter), "filter step missing 'filter' field")
		ll.assert(!is_undefined(step.filter.columnId),
			"filter step's filter missing 'columnId' field")
		return step.filter.columnId
	}
	ll.panic("unknown step type: %v", step.type)
}











buildQuery := func(input) {
	ll.assert(ll.isMap(input), "buildQuery: input must be a map, got %v", input)
	version := input.version
	ll.assert(version == "v1",
		"buildQuery: unsupported version %v (expected \"v1\")", version)

	column := input.column
	ll.assert(is_string(column),
		"buildQuery: 'column' must be a string, got %v", column)

	path := input.path
	if is_undefined(path) {
		path = []
	}
	ll.assert(is_array(path), "buildQuery: 'path' must be an array")

	qualifications := input.qualifications
	if is_undefined(qualifications) {
		qualifications = []
	}
	ll.assert(is_array(qualifications),
		"buildQuery: 'qualifications' must be an array")

	current := columnEntry(column, [])
	for i := len(path) - 1; i >= 0; i-- {
		step := path[i]
		colId := stepColumnId(step)
		if step.type == "linker" {
			current = wrapLinker(current, colId)
		} else {
			current = wrapFilter(current, colId)
		}
	}

	if len(qualifications) == 0 {
		return current
	}
	current.qualifications = qualifications
	return current
}

export ll.toStrict({
	buildQuery: buildQuery,
	columnEntry: columnEntry,
	linkerJoinEntry: linkerJoinEntry,
	innerJoinEntry: innerJoinEntry
})
