



ll := import("@platforma-sdk/workflow-tengo:ll")
smart := import("@platforma-sdk/workflow-tengo:smart")
oop := import("@platforma-sdk/workflow-tengo:oop")
maps := import("@platforma-sdk/workflow-tengo:maps")
validation := import("@platforma-sdk/workflow-tengo:validation")
pkg := import("@platforma-sdk/workflow-tengo:exec.package")

_RTYPE_SAVE_RUN_ENV   := { Name: "SaveRunEnv/executor", Version: "1" }
_INPUT_SETTINGS       := "settings"
_INPUT_WD_IN          := "workdirIn"
_INPUT_PACKAGES_MAP   := "packagesMap"

_OUTPUT_RUN_ENV       := "runEnv"
_OUTPUT_WD_OUT        := "workdirOut"

saveBuilder := func(wd) {
	self := undefined

	pathsToSave := []
	envType := ""

	packagesMap := {}

	self = {
		addPath: func(path) {
			validation.assertType(path, "string", "runenv.saveBuilder.addPath: <path> must be string")

			pathsToSave = append(pathsToSave, path)
			return self
		},

		envType: func(type) {
			validation.assertType(type, "string", "runenv.saveBuilder.envType: <type> must be string")

			envType = type
			return self
		},




		addPackage: func(key, pkgRef) {
			ll.assert(!maps.containsKey(packagesMap, key), "runenv.saveBuilder.addPackage: package %q was already added to SaveRunEnv builder", key)
			validation.assertType(pkgRef, validation.reference, "runenv.saveBuilder.addPackage: <pkgRef> must be reference")

			packagesMap[key] = pkgRef
			return self
		},

		build: func() {
			ll.assert(envType != "", "runenv.saveBuilder.build: environment type is not set")

			envSaver := smart.ephemeralBuilder(_RTYPE_SAVE_RUN_ENV)

			envSaver.getField(_INPUT_WD_IN).set(wd)

			envSaver.getField(_INPUT_SETTINGS).
				set(smart.createJsonResource({
					paths: pathsToSave,
					type: envType
				}))

			envSaver.getField(_INPUT_PACKAGES_MAP).
				set(smart.createMapResource(packagesMap))

			return oop.inherit(envSaver.lockAndBuild(), {






				runEnv: func() {
					return envSaver.getField(_OUTPUT_RUN_ENV)
				},







				workdir: func() {
					return envSaver.getField(_OUTPUT_WD_OUT)
				}
			})
		}
	}

	return self
}

loadDependencyFiles := func(packageRef, dependencies) {
	if len(dependencies) == 0 {
		return {}
	}

	depsMap := {}

	loader := pkg.pkgFileLoader(packageRef)
	for depName, fileName in dependencies {
		loader.saveFile(fileName)
	}
	deps := loader.load()

	for depName, fileName in dependencies {
		depsMap[depName] = deps.getFile(fileName)
	}

	return depsMap
}

export ll.toStrict({
	saveBuilder                        : saveBuilder,
	loadDependencyFiles                : loadDependencyFiles
})
