



ll := import("@platforma-sdk/workflow-tengo:ll")
smart := import("@platforma-sdk/workflow-tengo:smart")
workdir := import("@platforma-sdk/workflow-tengo:workdir")
oop := import("@platforma-sdk/workflow-tengo:oop")
sets := import("@platforma-sdk/workflow-tengo:sets")
validation := import("@platforma-sdk/workflow-tengo:validation")
json := import("json")
desc := import("@platforma-sdk/workflow-tengo:exec.descriptor")

softwareInfoScheme := {
	"name": "string",
	"version": "string",
	"descriptor": desc.scheme
}

META_KEY_DESCRIPTOR := "ctl/runner/package/descriptor"

_RTYPE_PACKAGE_GET := { Name: "PackageGet", Version: "1" }
_INPUT_PACKAGE_NAME := "packageName"
_INPUT_REGISTRY := "registry"
_OUTPUT_ARCHIVE := "archive"

get := func(registryName, pkgName) {
	res := smart.structBuilder(_RTYPE_PACKAGE_GET)

	res.getField(_INPUT_REGISTRY).setRefOrJson(registryName)
	res.getField(_INPUT_PACKAGE_NAME).setRefOrJson(pkgName)

	self := undefined
	self = oop.inherit(res, {





		archive: func() {
			return res.outputs()[_OUTPUT_ARCHIVE]
		}
	})

	return self
}

_RTYPE_PACKAGE_INSTALL := { Name: "PackageInstall", Version: "1" }
_INPUT_ARCHIVE := "archive"
_OUTPUT_PACKAGE := "package"

install := func(archive) {
	ll.assert(smart.isReference(archive),
		"package.install: <archive> must be reference to package archive. It is usually obtained from package.get().archive")

	res := smart.structBuilder(_RTYPE_PACKAGE_INSTALL)

	res.getField(_INPUT_ARCHIVE).set(archive)

	self := undefined
	self = oop.inherit(res, {





		package: func() {
			return res.getField(_OUTPUT_PACKAGE)
		}
	})

	return self
}

_RTYPE_PACKAGE_USE := { Name: "PackageUse", Version: "1" }
_INPUT_PACKAGE_USE_SETTINGS := "settings"

_useSettingsSchema := {
	hash: ["or", "bytes", "string"],
	path: "string",
	descriptor: "any",
	origin: {
		registry: "string",
		url: "string",
		packageName: "string"
	}
}

use := func(settings) {
	res := smart.structBuilder(_RTYPE_PACKAGE_USE)

	validation.assertType(settings, _useSettingsSchema, "package.use(<settings>): settings have invalid format")
	settingsRes := smart.createJsonResource(settings)

	res.getField(_INPUT_PACKAGE_USE_SETTINGS).set(settingsRes)

	self := undefined
	self = oop.inherit(res, {





		package: func() {
			return res.outputs()[_OUTPUT_PACKAGE]
		}
	})

	return self
}

_RTYPE_PACKAGE_PUT_ASSET := { Name: "PackagePutAssetsToWD", Version: "1" }
_INPUT_PACKAGE := "package"
_INPUT_WD_IN := "workdirIn"
_OUTPUT_WD_OUT := "workdirOut"








pkgFileLoader := func(pkg) {
	ll.assert(smart.isReference(pkg),
		"package.pkgFileLoader: <pkg> must be reference to installed package. It is usually obtained from package.install().package")

	filePaths := []
	fileContentPaths := []

	self := undefined

	self = {
		saveFile: func(path) {
			validation.assertType(path, "string", "package.pkgFileLoader.saveFile: <path> must be string")
			filePaths = append(filePaths, path)

			return self
		},

		saveFiles: func(paths) {
			validation.assertType(paths, ["string"], "package.pkgFileLoader.saveFiles: <paths> must be array of strings")
			for p in paths {
				self.saveFile(p)
			}

			return self
		},

		saveFileContent: func(path) {
			validation.assertType(path, "string", "package.pkgFileLoader.saveFileContent: <path> must be string")
			fileContentPaths = append(fileContentPaths, path)
			return self
		},

		saveFilesContent: func(paths) {
			validation.assertType(paths, ["string"], "package.pkgFileLoader.saveFilesContent: <paths> must be array of strings")
			for p in paths {
				self.saveFileContent(p)
			}

			return self
		},

		load: func() {
			wd := workdir.create()

			allPaths := sets.fromSlice(filePaths)
			allPaths = sets.add(allPaths, fileContentPaths...)

			res := smart.ephemeralBuilder(_RTYPE_PACKAGE_PUT_ASSET, json.encode({
				paths: sets.toSlice(allPaths)
			}))

			res.getField(_INPUT_PACKAGE).set(pkg)
			res.getField(_INPUT_WD_IN).set(wd)

			wdAfter := res.getField(_OUTPUT_WD_OUT)

			wdSaveBuilder := workdir.save(wdAfter)
			for p in filePaths {
				wdSaveBuilder.saveFile(p)
			}
			for p in fileContentPaths {
				wdSaveBuilder.saveFileContent(p)
			}
			wdSave := wdSaveBuilder.build()

			return {
				files: wdSave.files,
				filesContent: wdSave.filesContent,
				progress: wdSave.progress,







				getFile: func(fileName) {
					return wdSave.files.getFutureInputField(fileName)
				},







				getFileContent: func(fileName) {
					return wdSave.filesContent.getFutureInputField(fileName)
				}
			}
		}
	}

	return ll.toStrict(self)
}









loadPackageFile := func(pkg, assetPath) {
	assets := pkgFileLoader(pkg).
		saveFile(assetPath).
		load()

	return {
		file: assets.getFile(assetPath),
		progress: assets.progress
	}
}









loadPackageFileContent := func(pkg, assetPath) {
	assets := pkgFileLoader(pkg).
		saveFileContent(assetPath).
		load()

	return {
		content: assets.getFileContent(assetPath),
		progress: assets.progress
	}
}


export ll.toStrict({
	softwareInfoScheme                 : softwareInfoScheme,

	META_KEY_DESCRIPTOR                : META_KEY_DESCRIPTOR,

	get                                : get,
	install                            : install,
	use                                : use,
	pkgFileLoader                      : pkgFileLoader,
	loadPackageFile                    : loadPackageFile,
	loadPackageFileContent             : loadPackageFileContent
})
