class PythonEnvUtils {

	static PythonEnvironment preparePythonEnvironment(
		ReadableConfig config,
		String entryPointScript,
		String tmpDir) throws IOException {
		PythonEnvironment env = new PythonEnvironment();

		// 1. set the path of python interpreter.
		String pythonExec = config.getOptional(PYTHON_CLIENT_EXECUTABLE)
			.orElse(System.getenv(PYFLINK_CLIENT_EXECUTABLE));
		if (pythonExec != null) {
			env.pythonExec = pythonExec;
		}

		// 2. setup temporary local directory for the user files
		tmpDir = new File(tmpDir).getAbsolutePath();
		Path tmpDirPath = new Path(tmpDir);
		tmpDirPath.getFileSystem().mkdirs(tmpDirPath);
		env.tempDirectory = tmpDir;

		// 3. append the internal lib files to PYTHONPATH.
		if (System.getenv(ConfigConstants.ENV_FLINK_OPT_DIR) != null) {
			String pythonLibDir = System.getenv(ConfigConstants.ENV_FLINK_OPT_DIR) + File.separator + "python";
			env.pythonPath = getLibFiles(pythonLibDir).stream()
				.map(p -> p.toFile().getAbsolutePath())
				.collect(Collectors.joining(File.pathSeparator));
		}

		// 4. copy relevant python files to tmp dir and set them in PYTHONPATH.
		if (config.getOptional(PYTHON_FILES).isPresent()) {
			List<Path> pythonFiles = Arrays.stream(config.get(PYTHON_FILES).split(FILE_DELIMITER))
				.map(Path::new).collect(Collectors.toList());
			addToPythonPath(env, pythonFiles);
		}
		if (entryPointScript != null) {
			addToPythonPath(env, Collections.singletonList(new Path(entryPointScript)));
		}
		return env;
	}

}