/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.tools.ant.types;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.JavaEnvUtils;

/**
 * A representation of a Java command line that is
 * a composite of 2 <code>Commandline</code>s. One is used for the
 * vm/options and one for the classname/arguments. It provides
 * specific methods for a Java command line.
 *
 */
public class CommandlineJava implements Cloneable {

    /**
     * commands to the JVM
     */
    private Commandline vmCommand = new Commandline();
    /**
     * actual java commands
     */
    private Commandline javaCommand = new Commandline();
    /**
     * properties to add using -D
     */
    private SysProperties sysProperties = new SysProperties();
    private Path classpath = null;
    private Path bootclasspath = null;
    private Path modulepath = null;
    private Path upgrademodulepath = null;
    private String vmVersion;
    private String maxMemory = null;
    /**
     *  any assertions to make? Currently only supported in forked JVMs
     */
    private Assertions assertions = null;

    /**
     * Indicate whether it will execute a jar file, module or main class.
     * In this case of jar the first vm option must be a -jar and the 'executable' is a jar file.
     * In case of module the first vm option is -m and the 'executable' is 'module/mainClass'.
     */
     private ExecutableType executableType;

    /**
     * Whether system properties and bootclasspath shall be cloned.
     * @since Ant 1.7
     */
    private boolean cloneVm = false;

    /**
     * Specialized Environment class for System properties.
     */
    public static class SysProperties extends Environment implements Cloneable {
        // CheckStyle:VisibilityModifier OFF - bc
        /** the system properties. */
        Properties sys = null;
        // CheckStyle:VisibilityModifier ON
        private Vector<PropertySet> propertySets = new Vector<>();

        /**
         * Get the properties as an array; this is an override of the
         * superclass, as it evaluates all the properties.
         * @return the array of definitions; may be null.
         * @throws BuildException on error.
         */
        @Override
        public String[] getVariables() throws BuildException {

            List<String> definitions = new LinkedList<>();
            addDefinitionsToList(definitions.listIterator());
            if (definitions.isEmpty()) {
                return null;
            }
            return definitions.toArray(new String[definitions.size()]);
        }

        /**
         * Add all definitions (including property sets) to a list.
         * @param listIt list iterator supporting add method.
         */
        public void addDefinitionsToList(ListIterator<String> listIt) {
            String[] props = super.getVariables();
            if (props != null) {
                for (String prop : props) {
                    listIt.add("-D" + prop);
                }
            }
            Properties propertySetProperties = mergePropertySets();
            for (String key : propertySetProperties.stringPropertyNames()) {
                listIt.add("-D" + key + "=" + propertySetProperties.getProperty(key));
            }
        }

        /**
         * Get the size of the sysproperties instance. This merges all
         * property sets, so is not an O(1) operation.
         * @return the size of the sysproperties instance.
         */
        public int size() {
            Properties p = mergePropertySets();
            return variables.size() + p.size();
        }

        /**
         * Cache the system properties and set the system properties to the
         * new values.
         * @throws BuildException if Security prevented this operation.
         */
        public void setSystem() throws BuildException {
            try {
                sys = System.getProperties();
                Properties p = new Properties();
                for (String name : sys.stringPropertyNames()) {
                    String value = sys.getProperty(name);
                    if (value != null) {
                        p.put(name, value);
                    }
                }
                p.putAll(mergePropertySets());
                for (Environment.Variable v : variables) {
                    v.validate();
                    p.put(v.getKey(), v.getValue());
                }
                System.setProperties(p);
            } catch (SecurityException e) {
                throw new BuildException("Cannot modify system properties", e);
            }
        }

        /**
         * Restore the system properties to the cached value.
         * @throws BuildException  if Security prevented this operation, or
         * there were no system properties to restore.
         */
        public void restoreSystem() throws BuildException {
            if (sys == null) {
                throw new BuildException("Unbalanced nesting of SysProperties");
            }

            try {
                System.setProperties(sys);
                sys = null;
            } catch (SecurityException e) {
                throw new BuildException("Cannot modify system properties", e);
            }
        }

        /**
         * Create a deep clone.
         * @return a cloned instance of SysProperties.
         * @exception CloneNotSupportedException for signature.
         */
        @SuppressWarnings("unchecked")
        @Override
        public Object clone() throws CloneNotSupportedException {
            try {
                SysProperties c = (SysProperties) super.clone();
                c.variables = (Vector<Environment.Variable>) variables.clone();
                c.propertySets = (Vector<PropertySet>) propertySets.clone();
                return c;
            } catch (CloneNotSupportedException e) {
                return null;
            }
        }

        /**
         * Add a propertyset to the total set.
         * @param ps the new property set.
         */
        public void addSyspropertyset(PropertySet ps) {
            propertySets.addElement(ps);
        }

        /**
         * Add a propertyset to the total set.
         * @param ps the new property set.
         * @since Ant 1.6.3
         */
        public void addSysproperties(SysProperties ps) {
            variables.addAll(ps.variables);
            propertySets.addAll(ps.propertySets);
        }

        /**
         * Merge all property sets into a single Properties object.
         * @return the merged object.
         */
        private Properties mergePropertySets() {
            Properties p = new Properties();
            for (PropertySet ps : propertySets) {
                p.putAll(ps.getProperties());
            }
            return p;
        }

    }

    /**
     * Constructor uses the VM we are running on now.
     */
    public CommandlineJava() {
        setVm(JavaEnvUtils.getJreExecutable("java"));
        setVmversion(JavaEnvUtils.getJavaVersion());
    }

    /**
     * Create a new argument to the java program.
     * @return an argument to be configured.
     */
    public Commandline.Argument createArgument() {
        return javaCommand.createArgument();
    }

    /**
     * Create a new JVM argument.
     * @return an argument to be configured.
     */
    public Commandline.Argument createVmArgument() {
        return vmCommand.createArgument();
    }

    /**
     * Add a system property.
     * @param sysp a property to be set in the JVM.
     */
    public void addSysproperty(Environment.Variable sysp) {
        sysProperties.addVariable(sysp);
    }

    /**
     * Add a set of system properties.
     * @param sysp a set of properties.
     */
    public void addSyspropertyset(PropertySet sysp) {
        sysProperties.addSyspropertyset(sysp);
    }

    /**
     * Add a set of system properties.
     * @param sysp a set of properties.
     * @since Ant 1.6.3
     */
    public void addSysproperties(SysProperties sysp) {
        sysProperties.addSysproperties(sysp);
    }

    /**
     * Set the executable used to start the new JVM.
     * @param vm the executable to use.
     */
    public void setVm(String vm) {
        vmCommand.setExecutable(vm);
    }

    /**
     * Set the JVM version required.
     * @param value the version required.
     */
    public void setVmversion(String value) {
        vmVersion = value;
    }

    /**
     * Set whether system properties will be copied to the cloned VM--as
     * well as the bootclasspath unless you have explicitly specified
     * a bootclasspath.
     * @param cloneVm if true copy the system properties.
     * @since Ant 1.7
     */
    public void setCloneVm(boolean cloneVm) {
        this.cloneVm = cloneVm;
    }

    /**
     * Get the current assertions.
     * @return assertions or null.
     */
    public Assertions getAssertions() {
        return assertions;
    }

    /**
     * Add an assertion set to the command.
     * @param assertions assertions to make.
     */
    public void setAssertions(Assertions assertions) {
        this.assertions = assertions;
    }

    /**
     * Set a jar file to execute via the -jar option.
     * @param jarpathname the pathname of the jar to execute.
     */
    public void setJar(String jarpathname) {
        javaCommand.setExecutable(jarpathname);
        executableType = ExecutableType.JAR;
    }

    /**
     * Get the name of the jar to be run.
     * @return the pathname of the jar file to run via -jar option
     * or <code>null</code> if there is no jar to run.
     * @see #getClassname()
     */
    public String getJar() {
        if (executableType == ExecutableType.JAR) {
            return javaCommand.getExecutable();
        }
        return null;
    }

    /**
     * Set the classname to execute.
     * @param classname the fully qualified classname.
     */
    public void setClassname(String classname) {
        if (executableType == ExecutableType.MODULE) {
            javaCommand.setExecutable(createModuleClassPair(
                    parseModuleFromModuleClassPair(javaCommand.getExecutable()),
                    classname), false);
        } else {
            javaCommand.setExecutable(classname);
            executableType = ExecutableType.CLASS;
        }
    }

    /**
     * Get the name of the class to be run.
     * @return the name of the class to run or <code>null</code> if there is no class.
     * @see #getJar()
     */
    public String getClassname() {
        if (executableType != null) {
            switch (executableType) {
                case CLASS:
                    return javaCommand.getExecutable();
                case MODULE:
                    return parseClassFromModuleClassPair(javaCommand.getExecutable());
                default:
            }
        }
        return null;
    }

    /**
     * Set the source-file, to execute as single file source programs, a feature, available
     * since Java 11.
     *
     * @param sourceFile The path to the source file
     * @since Ant 1.10.5
     */
    public void setSourceFile(final String sourceFile) {
        this.executableType = ExecutableType.SOURCE_FILE;
        javaCommand.setExecutable(sourceFile);
    }

    /**
     * @return Returns the source-file to execute, if this command line has
     * been {@link #setSourceFile(String) configured for single file source program
     * execution}. Else returns null.
     * @since Ant 1.10.5
     */
    public String getSourceFile() {
        return this.executableType == ExecutableType.SOURCE_FILE ? this.javaCommand.getExecutable() : null;
    }

    /**
     * Set the module to execute.
     * @param module  the module name.
     * @since 1.9.7
     */
    public void setModule(final String module) {
        if (executableType == null) {
            javaCommand.setExecutable(module);
        } else {
            switch (executableType) {
                case JAR:
                    javaCommand.setExecutable(module, false);
                    break;
                case CLASS:
                    javaCommand.setExecutable(createModuleClassPair(module,
                            javaCommand.getExecutable()), false);
                    break;
                case MODULE:
                    javaCommand.setExecutable(createModuleClassPair(module,
                            parseClassFromModuleClassPair(javaCommand.getExecutable())), false);
                    break;
                default:
            }
        }
        executableType = ExecutableType.MODULE;
    }

    /**
     * Get the name of the module to be run.
     * @return the name of the module to run or <code>null</code> if there is no module.
     * @see #getJar()
     * @see #getClassname()
     * @since 1.9.7
     */
    public String getModule() {
        if (executableType == ExecutableType.MODULE) {
            return parseModuleFromModuleClassPair(javaCommand.getExecutable());
        }
        return null;
    }

    /**
     * Create a classpath.
     * @param p the project to use to create the path.
     * @return a path to be configured.
     */
    public Path createClasspath(Project p) {
        if (classpath == null) {
            classpath = new Path(p);
        }
        return classpath;
    }

    /**
     * Create a boot classpath.
     * @param p the project to use to create the path.
     * @return a path to be configured.
     * @since Ant 1.6
     */
    public Path createBootclasspath(Project p) {
        if (bootclasspath == null) {
            bootclasspath = new Path(p);
        }
        return bootclasspath;
    }

    /**
     * Create a modulepath.
     * @param p the project to use to create the path.
     * @return a path to be configured.
     * @since 1.9.7
     */
    public Path createModulepath(Project p) {
        if (modulepath == null) {
            modulepath = new Path(p);
        }
        return modulepath;
    }

    /**
     * Create an upgrademodulepath.
     * @param p the project to use to create the path.
     * @return a path to be configured.
     * @since 1.9.7
     */
    public Path createUpgrademodulepath(Project p) {
        if (upgrademodulepath == null) {
            upgrademodulepath = new Path(p);
        }
        return upgrademodulepath;
    }

    /**
     * Get the vm version.
     * @return the vm version.
     */
    public String getVmversion() {
        return vmVersion;
    }

    /**
     * Get the command line to run a Java vm.
     * @return the list of all arguments necessary to run the vm.
     */
    public String[] getCommandline() {
        //create the list
        List<String> commands = new LinkedList<>();
        //fill it
        addCommandsToList(commands.listIterator());
        //convert to an array
        return commands.toArray(new String[commands.size()]);
    }

    /**
     * Add all the commands to a list identified by the iterator passed in.
     * @param listIterator an iterator that supports the add method.
     * @since Ant 1.6
     */
    private void addCommandsToList(final ListIterator<String> listIterator) {
        //create the command to run Java, including user specified options
        getActualVMCommand().addCommandToList(listIterator);
        // properties are part of the vm options...
        sysProperties.addDefinitionsToList(listIterator);

        if (isCloneVm()) {
            SysProperties clonedSysProperties = new SysProperties();
            PropertySet ps = new PropertySet();
            PropertySet.BuiltinPropertySetName sys = new PropertySet.BuiltinPropertySetName();
            sys.setValue("system");
            ps.appendBuiltin(sys);
            clonedSysProperties.addSyspropertyset(ps);
            clonedSysProperties.addDefinitionsToList(listIterator);
        }
        //boot classpath
        Path bcp = calculateBootclasspath(true);
        if (bcp.size() > 0) {
            listIterator.add("-Xbootclasspath:" + bcp.toString());
        }
        //main classpath
        if (haveClasspath()) {
            listIterator.add("-classpath");
            listIterator.add(classpath.concatSystemClasspath("ignore").toString());
        }
        //module path
        if (haveModulepath()) {
            listIterator.add("--module-path");
            listIterator.add(modulepath.concatSystemClasspath("ignore").toString());
        }
        //upgrade module path
        if (haveUpgrademodulepath()) {
            listIterator.add("--upgrade-module-path");
            listIterator.add(upgrademodulepath.concatSystemClasspath("ignore").toString());
        }
        //now any assertions are added
        if (getAssertions() != null) {
            getAssertions().applyAssertions(listIterator);
        }
        // JDK usage command line says that -jar must be the first option, as there is
        // a bug in JDK < 1.4 that forces the jvm type to be specified as the first
        // option, it is appended here as specified in the docs even though there is
        // in fact no order.
        if (executableType == ExecutableType.JAR) {
            listIterator.add("-jar");
        } else if (executableType == ExecutableType.MODULE) {
            listIterator.add("-m");
        }
        // this is the classname/source-file to run as well as its arguments.
        // in case of ExecutableType.JAR, the executable is a jar file,
        // in case of ExecutableType.MODULE, the executable is a module name, potentially including a class name.
        // in case of ExecutableType.SOURCE_FILE, the executable is a Java source file (ending in .java) or a shebang
        // file containing Java source
        javaCommand.addCommandToList(listIterator);
    }

    /**
     * Specify max memory of the JVM.
     * -mx or -Xmx depending on VM version.
     * @param max the string to pass to the jvm to specify the max memory.
     */
    public void setMaxmemory(String max) {
        this.maxMemory = max;
    }

    /**
     * Get a string description.
     * @return the command line as a string.
     */
    @Override
    public String toString() {
        return Commandline.toString(getCommandline());
    }

    /**
     * Return a String that describes the command and arguments suitable for
     * verbose output before a call to <code>Runtime.exec(String[])</code>.
     * @return the description string.
     * @since Ant 1.5
     */
    public String describeCommand() {
        return Commandline.describeCommand(getCommandline());
    }

    /**
     * Return a String that describes the java command and arguments
     * for in-VM executions.
     *
     * <p>The class name is the executable in this context.</p>
     * @return the description string.
     * @since Ant 1.5
     */
    public String describeJavaCommand() {
        return Commandline.describeCommand(getJavaCommand());
    }

    /**
     * Get the VM command parameters, including memory settings.
     * @return the VM command parameters.
     */
    protected Commandline getActualVMCommand() {
        Commandline actualVMCommand = (Commandline) vmCommand.clone();
        if (maxMemory != null) {
            if (vmVersion.startsWith("1.1")) {
                actualVMCommand.createArgument().setValue("-mx" + maxMemory);
            } else {
                actualVMCommand.createArgument().setValue("-Xmx" + maxMemory);
            }
        }
        return actualVMCommand;
    }

    /**
     * Get the size of the java command line. This is a fairly intensive
     * operation, as it has to evaluate the size of many components.
     * @return the total number of arguments in the java command line.
     * @see #getCommandline()
     * @deprecated since 1.7.
     *             Please don't use this, it effectively creates the
     *             entire command.
     */
    @Deprecated
    public int size() {
        int size = getActualVMCommand().size() + javaCommand.size()
            + sysProperties.size();
        // cloned system properties
        if (isCloneVm()) {
            size += System.getProperties().size();
        }
        // classpath is "-classpath <classpath>" -> 2 args
        if (haveClasspath()) {
            size += 2;
        }
        // bootclasspath is "-Xbootclasspath:<classpath>" -> 1 arg
        if (calculateBootclasspath(true).size() > 0) {
            size++;
        }
        // jar execution requires an additional -jar option
        if (executableType == ExecutableType.JAR || executableType == ExecutableType.MODULE) {
            size++;
        }
        //assertions take up space too
        if (getAssertions() != null) {
            size += getAssertions().size();
        }
        return size;
    }

    /**
     * Get the Java command to be used.
     * @return the java command--not a clone.
     */
    public Commandline getJavaCommand() {
        return javaCommand;
    }

    /**
     * Get the VM command, including memory.
     * @return A deep clone of the instance's VM command, with memory settings added.
     */
    public Commandline getVmCommand() {
        return getActualVMCommand();
    }

    /**
     * Get the classpath for the command.
     * @return the classpath or null.
     */
    public Path getClasspath() {
        return classpath;
    }

    /**
     * Get the boot classpath.
     * @return boot classpath or null.
     */
    public Path getBootclasspath() {
        return bootclasspath;
    }

    /**
     * Get the modulepath.
     * @return modulepath or null.
     * @since 1.9.7
     */
    public Path getModulepath() {
        return modulepath;
    }

    /**
     * Get the upgrademodulepath.
     * @return upgrademodulepath or null.
     * @since 1.9.7
     */
    public Path getUpgrademodulepath() {
        return upgrademodulepath;
    }

    /**
     * Cache current system properties and set them to those in this
     * Java command.
     * @throws BuildException  if Security prevented this operation.
     */
    public void setSystemProperties() throws BuildException {
        sysProperties.setSystem();
    }

    /**
     * Restore the cached system properties.
     * @throws BuildException  if Security prevented this operation, or
     * there was no system properties to restore
     */
    public void restoreSystemProperties() throws BuildException {
        sysProperties.restoreSystem();
    }

    /**
     * Get the system properties object.
     * @return The system properties object.
     */
    public SysProperties getSystemProperties() {
        return sysProperties;
    }

    /**
     * Deep clone the object.
     * @return a CommandlineJava object.
     * @throws BuildException if anything went wrong.
     * @throws CloneNotSupportedException never.
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        try {
            CommandlineJava c = (CommandlineJava) super.clone();
            c.vmCommand = (Commandline) vmCommand.clone();
            c.javaCommand = (Commandline) javaCommand.clone();
            c.sysProperties = (SysProperties) sysProperties.clone();
            if (classpath != null) {
                c.classpath = (Path) classpath.clone();
            }
            if (bootclasspath != null) {
                c.bootclasspath = (Path) bootclasspath.clone();
            }
            if (modulepath != null) {
                c.modulepath = (Path) modulepath.clone();
            }
            if (upgrademodulepath != null) {
                c.upgrademodulepath = (Path) upgrademodulepath.clone();
            }
            if (assertions != null) {
                c.assertions = (Assertions) assertions.clone();
            }
            return c;
        } catch (CloneNotSupportedException e) {
            throw new BuildException(e);
        }
    }

    /**
     * Clear out the java arguments.
     */
    public void clearJavaArgs() {
        javaCommand.clearArgs();
    }

    /**
     * Determine whether the classpath has been specified, and whether it shall
     * really be used or be nulled by build.sysclasspath.
     * @return true if the classpath is to be used.
     * @since Ant 1.6
     */
    public boolean haveClasspath() {
        Path fullClasspath = classpath == null ? null : classpath.concatSystemClasspath("ignore");
        return fullClasspath != null && !fullClasspath.toString().trim().isEmpty();
    }

    /**
     * Determine whether the bootclasspath has been specified, and whether it
     * shall really be used (build.sysclasspath could be set or the VM may not
     * support it).
     *
     * @param log whether to log a warning if a bootclasspath has been
     * specified but will be ignored.
     * @return true if the bootclasspath is to be used.
     * @since Ant 1.6
     */
    protected boolean haveBootclasspath(boolean log) {
        return calculateBootclasspath(log).size() > 0;
    }

    /**
     * Determine whether the modulepath has been specified.
     * @return true if the modulepath is to be used.
     * @since 1.9.7
     */
    public boolean haveModulepath() {
        Path fullClasspath = modulepath != null
                ? modulepath.concatSystemClasspath("ignore") : null;
        return fullClasspath != null
            && !fullClasspath.toString().trim().isEmpty();
    }

    /**
     * Determine whether the upgrademodulepath has been specified.
     * @return true if the upgrademodulepath is to be used.
     * @since 1.9.7
     */
    public boolean haveUpgrademodulepath() {
        Path fullClasspath = upgrademodulepath != null
                ? upgrademodulepath.concatSystemClasspath("ignore") : null;
        return fullClasspath != null && !fullClasspath.toString().trim().isEmpty();
    }

    /**
     * Calculate the bootclasspath based on the bootclasspath
     * specified, the build.sysclasspath and ant.build.clonevm magic
     * properties as well as the cloneVm attribute.
     * @param log whether to write messages to the log.
     * @since Ant 1.7
     */
    private Path calculateBootclasspath(boolean log) {
        if (vmVersion.startsWith("1.1")) {
            if (bootclasspath != null && log) {
                bootclasspath.log("Ignoring bootclasspath as the target VM doesn't support it.");
            }
        } else {
            Path b = bootclasspath;
            if (b == null) {
                b = new Path(null);
            }
            // even with no user-supplied bootclasspath
            // build.sysclasspath could be set to something other than
            // "ignore" and thus create one
            return b.concatSystemBootClasspath(isCloneVm() ? "last" : "ignore");
        }
        return new Path(null);
    }

    /**
     * Find out whether either of the cloneVm attribute or the magic property
     * ant.build.clonevm has been set.
     * @return <code>boolean</code>.
     * @since 1.7
     */
    private boolean isCloneVm() {
        return cloneVm || Boolean.parseBoolean(System.getProperty("ant.build.clonevm"));
    }

    /**
     * Creates JDK 9 main module command line argument.
     * @param module the module name.
     * @param classname the classname or <code>null</code>.
     * @return the main module with optional classname command line argument.
     * @since 1.9.7
     */
    private static String createModuleClassPair(final String module, final String classname) {
        return classname == null ? module : String.format("%s/%s", module, classname);   //NOI18N
    }

    /**
     * Parses a module name from JDK 9 main module command line argument.
     * @param moduleClassPair a module with optional classname or <code>null</code>.
     * @return the module name or <code>null</code>.
     * @since 1.9.7
     */
    private static String parseModuleFromModuleClassPair(final String moduleClassPair) {
        if (moduleClassPair == null) {
            return null;
        }
        final String[] moduleAndClass = moduleClassPair.split("/");  //NOI18N
        return moduleAndClass[0];
    }

    /**
     * Parses a classname from JDK 9 main module command line argument.
     * @param moduleClassPair a module with optional classname or <code>null</code>.
     * @return the classname or <code>null</code>.
     * @since 1.9.7
     */
    private static String parseClassFromModuleClassPair(final String moduleClassPair) {
        if (moduleClassPair == null) {
            return null;
        }
        final String[] moduleAndClass = moduleClassPair.split("/");  //NOI18N
        return moduleAndClass.length == 2 ? moduleAndClass[1] : null;
    }

    /**
     * Type of execution.
     * @since 1.9.7
     */
    private enum ExecutableType {
        /**
         * Main class execution.
         */
        CLASS,
        /**
         * Jar file execution.
         */
        JAR,
        /**
         * Module execution.
         */
        MODULE,

        /**
         * Source file (introduced in Java 11)
         */
        SOURCE_FILE,
    }
}
