/*
 *  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.ivy;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.deliver.DeliverOptions;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.publish.PublishOptions;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolveProcessException;
import org.apache.ivy.core.retrieve.RetrieveOptions;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorWriter;
import org.apache.ivy.plugins.parser.m2.PomWriterOptions;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
import org.apache.ivy.plugins.report.XmlReportParser;
import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.PropertiesFile;
import org.apache.ivy.util.cli.CommandLine;
import org.apache.ivy.util.cli.CommandLineParser;
import org.apache.ivy.util.cli.OptionBuilder;
import org.apache.ivy.util.cli.ParseException;
import org.apache.ivy.util.filter.FilterHelper;
import org.apache.ivy.util.url.CredentialsStore;
import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
import org.apache.ivy.util.url.URLHandlerDispatcher;
import org.apache.ivy.util.url.URLHandlerRegistry;

/**
 * Class used to launch ivy as a standalone tool.
 * <p>
 * Valid arguments can be obtained with the -? argument.
 */
public final class Main {
    private static final int HELP_WIDTH = 80;

    static CommandLineParser getParser() {
        return new CommandLineParser()
                .addCategory("settings options")
                .addOption(
                    new OptionBuilder("settings").arg("settingsfile|url")
                            .description("use given file or URL for settings").create())
                .addOption(
                        new OptionBuilder("properties").arg("propertiesfile")
                            .description("use given file for properties not specified in settings").create())
                .addOption(
                    new OptionBuilder("cache").arg("cachedir")
                            .description("use given directory for cache").create())
                .addOption(
                    new OptionBuilder("novalidate").description(
                        "do not validate ivy files against xsd").create())
                .addOption(
                    new OptionBuilder("m2compatible").description("use Maven 2 compatibility")
                            .create())
                .addOption(
                    new OptionBuilder("conf").arg("settingsfile").deprecated()
                            .description("use given file for settings").create())
                .addOption(
                    new OptionBuilder("useOrigin")
                            .deprecated()
                            .description(
                                "use original artifact location "
                                        + "with local resolvers instead of copying to the cache")
                            .create())

                .addCategory("resolve options")
                .addOption(
                    new OptionBuilder("ivy").arg("ivyfile")
                            .description("use given file as ivy file").create())
                .addOption(
                    new OptionBuilder("refresh").description("refresh dynamic resolved revisions")
                            .create())
                .addOption(
                    new OptionBuilder("dependency")
                            .arg("organisation")
                            .arg("module")
                            .arg("revision")
                            .description(
                                "use this instead of ivy file to do the rest "
                                        + "of the work with this as a dependency.").create())
                .addOption(
                    new OptionBuilder("confs").arg("configurations").countArgs(false)
                            .description("resolve given configurations").create())
                .addOption(
                    new OptionBuilder("types").arg("types").countArgs(false)
                            .description("accepted artifact types")
                            .create())
                .addOption(
                    new OptionBuilder("mode").arg("resolvemode")
                            .description("the resolve mode to use").create())
                .addOption(
                    new OptionBuilder("notransitive").description(
                        "do not resolve dependencies transitively").create())

                .addCategory("retrieve options")
                .addOption(
                    new OptionBuilder("retrieve").arg("retrievepattern")
                            .description("use given pattern as retrieve pattern").create())
                .addOption(
                    new OptionBuilder("ivypattern").arg("pattern")
                            .description("use given pattern to copy the ivy files").create())
                .addOption(
                    new OptionBuilder("sync").description("use sync mode for retrieve").create())
                .addOption(
                    new OptionBuilder("symlink").description("create symbolic links").create())
                .addOption(new OptionBuilder("overwriteMode").arg("overwriteMode")
                        .description("use given overwrite mode for retrieve")
                        .create())
                .addCategory("cache path options")
                .addOption(
                    new OptionBuilder("cachepath")
                            .arg("cachepathfile")
                            .description(
                                "outputs a classpath consisting of all dependencies in cache "
                                        + "(including transitive ones) "
                                        + "of the given ivy file to the given cachepathfile")
                            .create())

                .addCategory("deliver options")
                .addOption(
                    new OptionBuilder("deliverto").arg("ivypattern")
                            .description("use given pattern as resolved ivy file pattern").create())

                .addCategory("publish options")
                .addOption(
                    new OptionBuilder("publish").arg("resolvername")
                            .description("use given resolver to publish to").create())
                .addOption(
                    new OptionBuilder("publishpattern").arg("artpattern")
                            .description("use given pattern to find artifacts to publish").create())
                .addOption(
                    new OptionBuilder("revision").arg("revision")
                            .description("use given revision to publish the module").create())
                .addOption(
                    new OptionBuilder("status").arg("status")
                            .description("use given status to publish the module").create())
                .addOption(
                    new OptionBuilder("overwrite").description(
                        "overwrite files in the repository if they exist").create())

                .addCategory("makepom options")
                .addOption(new OptionBuilder("makepom").arg("pomfilepath")
                        .description("create a POM file for the module").create())

                .addCategory("http auth options")
                .addOption(
                    new OptionBuilder("realm").arg("realm")
                            .description("use given realm for HTTP AUTH").create())
                .addOption(
                    new OptionBuilder("host").arg("host")
                            .description("use given host for HTTP AUTH").create())
                .addOption(
                    new OptionBuilder("username").arg("username")
                            .description("use given username for HTTP AUTH").create())
                .addOption(
                    new OptionBuilder("passwd").arg("passwd")
                            .description("use given password for HTTP AUTH").create())

                .addCategory("launcher options")
                .addOption(
                    new OptionBuilder("main").arg("main")
                            .description("the FQCN of the main class to launch").create())
                .addOption(
                    new OptionBuilder("args").arg("args").countArgs(false)
                            .description("the arguments to give to the launched process").create())
                .addOption(
                    new OptionBuilder("cp").arg("cp")
                            .description("extra classpath to use when launching process").create())


                .addCategory("message options")
                .addOption(
                    new OptionBuilder("debug").description("set message level to debug").create())
                .addOption(
                    new OptionBuilder("verbose").description("set message level to verbose")
                            .create())
                .addOption(
                    new OptionBuilder("warn").description("set message level to warn").create())
                .addOption(
                    new OptionBuilder("error").description("set message level to error").create())

                .addCategory("help options")
                .addOption(new OptionBuilder("?").description("display this help").create())
                .addOption(
                    new OptionBuilder("deprecated").description("show deprecated options").create())
                .addOption(
                    new OptionBuilder("version").description("displays version information")
                            .create());
    }

    public static void main(String[] args) throws Exception {
        try {
            run(args, true);
            System.exit(0);
        } catch (ParseException ex) {
            System.err.println(ex.getMessage());
            System.exit(1);
        }
    }

    /**
     * A method that allows to run embedded Ivy as if it were launched from CLI
     * (e.g., for use with REPL in Java 9+).
     *
     * @param args an array of command line arguments
     * @return null if asked for usage or version, or if anything fails during resolve, publish or
     * launch; a ResolveReport on success
     * @throws Exception if something goes wrong
     */
    public static ResolveReport run(String[] args) throws Exception {
        return run(args, false);
    }

    /*
     * For backwards compatibility and testing
     */
    static void run(CommandLineParser parser, String[] args) throws Exception {
        if (Arrays.asList(args).contains("-?")) {
            usage(parser, false);
            return;
        }

        run(parser.parse(args), true);
    }

    private static ResolveReport run(String[] args, boolean isCli) throws Exception {
        CommandLineParser parser = getParser();

        // parse the command line arguments
        CommandLine line;
        try {
            line = parser.parse(args);
        } catch (ParseException pe) {
            // display usage and and rethrow
            usage(parser, false);
            throw new ParseException(pe.getMessage());
        }

        if (line.hasOption("?")) {
            usage(parser, line.hasOption("deprecated"));
            return null;
        }

        return run(line, isCli);
    }

    @SuppressWarnings("deprecation")
    private static ResolveReport run(CommandLine line, boolean isCli) throws Exception {
        if (line.hasOption("version")) {
            System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate()
                    + " :: " + Ivy.getIvyHomeURL());
            return null;
        }

        boolean validate = !line.hasOption("novalidate");

        Ivy ivy = Ivy.newInstance();
        initMessage(line, ivy);
        IvySettings settings = initSettings(line, ivy);
        ivy.pushContext();

        File cache = new File(settings.substitute(line.getOptionValue("cache", settings
                .getDefaultCache().getAbsolutePath())));

        if (line.hasOption("cache")) {
            // override default cache path with user supplied cache path
            settings.setDefaultCache(cache);
        }

        if (!cache.exists()) {
            cache.mkdirs();
        } else if (!cache.isDirectory()) {
            error(cache + " is not a directory");
        }

        String[] confs;
        if (line.hasOption("confs")) {
            confs = line.getOptionValues("confs");
        } else {
            confs = new String[] {"*"};
        }

        File ivyfile;
        if (line.hasOption("dependency")) {
            String[] dep = line.getOptionValues("dependency");
            ivyfile = File.createTempFile("ivy", ".xml");
            ivyfile.deleteOnExit();
            DefaultModuleDescriptor md = DefaultModuleDescriptor
                    .newDefaultInstance(ModuleRevisionId.newInstance(dep[0], dep[1] + "-caller",
                        "working"));
            DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
                    ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true);
            for (String conf : confs) {
                dd.addDependencyConfiguration("default", conf);
            }
            md.addDependency(dd);
            XmlModuleDescriptorWriter.write(md, ivyfile);
            confs = new String[] {"default"};
        } else {
            ivyfile = new File(settings.substitute(line.getOptionValue("ivy", "ivy.xml")));
            if (!ivyfile.exists()) {
                error("ivy file not found: " + ivyfile);
            } else if (ivyfile.isDirectory()) {
                error("ivy file is not a file: " + ivyfile);
            }
        }

        if (line.hasOption("useOrigin")) {
            ivy.getSettings().useDeprecatedUseOrigin();
        }
        ResolveOptions resolveOptions = new ResolveOptions()
                .setConfs(confs)
                .setValidate(validate)
                .setResolveMode(line.getOptionValue("mode"))
                .setArtifactFilter(
                    FilterHelper.getArtifactTypeFilter(line.getOptionValues("types")));
        if (line.hasOption("notransitive")) {
            resolveOptions.setTransitive(false);
        }
        if (line.hasOption("refresh")) {
            resolveOptions.setRefresh(true);
        }
        ResolveReport report = ivy.resolve(ivyfile.toURI().toURL(), resolveOptions);
        if (report.hasError()) {
            if (isCli) {
                System.exit(1);
            }

            StringBuilder sb = new StringBuilder();
            for (String problem : report.getAllProblemMessages()) {
                if (sb.length() > 0) {
                    sb.append("\n");
                }
                sb.append(problem);
            }
            throw new ResolveProcessException(sb.toString());
        }
        ModuleDescriptor md = report.getModuleDescriptor();

        if (confs.length == 1 && "*".equals(confs[0])) {
            confs = md.getConfigurationsNames();
        }
        if (line.hasOption("retrieve")) {
            String retrievePattern = settings.substitute(line.getOptionValue("retrieve"));
            if (!retrievePattern.contains("[")) {
                retrievePattern += "/lib/[conf]/[artifact].[ext]";
            }
            String ivyPattern = settings.substitute(line.getOptionValue("ivypattern"));
            ivy.retrieve(
                md.getModuleRevisionId(),
                new RetrieveOptions()
                        .setConfs(confs)
                        .setSync(line.hasOption("sync"))
                        .setUseOrigin(line.hasOption("useOrigin"))
                        .setDestArtifactPattern(retrievePattern)
                        .setDestIvyPattern(ivyPattern)
                        .setOverwriteMode(line.getOptionValue("overwriteMode"))
                        .setArtifactFilter(
                            FilterHelper.getArtifactTypeFilter(line.getOptionValues("types")))
                        .setMakeSymlinks(line.hasOption("symlink"))
                        .setMakeSymlinksInMass(line.hasOption("symlinkmass")));
        }
        if (line.hasOption("cachepath")) {
            outputCachePath(ivy, cache, md, confs,
                line.getOptionValue("cachepath", "ivycachepath.txt"));
        }

        if (line.hasOption("revision")) {
            ivy.deliver(
                md.getResolvedModuleRevisionId(),
                settings.substitute(line.getOptionValue("revision")),
                settings.substitute(line.getOptionValue("deliverto", "ivy-[revision].xml")),
                DeliverOptions.newInstance(settings)
                        .setStatus(settings.substitute(line.getOptionValue("status", "release")))
                        .setValidate(validate));
            if (line.hasOption("publish")) {
                ivy.publish(
                    md.getResolvedModuleRevisionId(),
                    Collections.singleton(settings.substitute(line.getOptionValue("publishpattern",
                        "distrib/[type]s/[artifact]-[revision].[ext]"))),
                    line.getOptionValue("publish"),
                    new PublishOptions()
                            .setPubrevision(settings.substitute(line.getOptionValue("revision")))
                            .setValidate(validate)
                            .setSrcIvyPattern(
                                settings.substitute(line.getOptionValue("deliverto",
                                    "ivy-[revision].xml")))
                            .setOverwrite(line.hasOption("overwrite")));
            }
        }
        if (line.hasOption("makepom")) {
            final String pomFilePath = line.getOptionValue("makepom", "pom.xml");
            final File pomFile = new File(pomFilePath);
            PomModuleDescriptorWriter.write(md, pomFile, new PomWriterOptions());
            Message.debug("Generated a pom file for module at " + pomFile);
        }
        if (line.hasOption("main")) {
            // check if the option cp has been set
            List<File> fileList = getExtraClasspathFileList(line);

            // merge -args and left over args
            String[] fargs = line.getOptionValues("args");
            if (fargs == null) {
                fargs = new String[0];
            }
            String[] extra = line.getLeftOverArgs();
            if (extra == null) {
                extra = new String[0];
            }
            String[] params = new String[fargs.length + extra.length];
            System.arraycopy(fargs, 0, params, 0, fargs.length);
            System.arraycopy(extra, 0, params, fargs.length, extra.length);
            // invoke with given main class and merged params
            invoke(ivy, cache, md, confs, fileList, line.getOptionValue("main"), params);
        }
        ivy.getLoggerEngine().popLogger();
        ivy.popContext();

        return report;
    }

    /**
     * Parses the <code>cp</code> option from the command line, and returns a list of {@link File}.
     * <p>
     * All the files contained in the returned List exist, non existing files are simply skipped
     * with a warning.
     * </p>
     *
     * @param line
     *            the command line in which the cp option should be parsed
     * @return a List of files to include as extra classpath entries, or <code>null</code> if no cp
     *         option was provided.
     */
    private static List<File> getExtraClasspathFileList(CommandLine line) {
        List<File> fileList = null;
        if (line.hasOption("cp")) {
            fileList = new ArrayList<>();
            for (String cp : line.getOptionValues("cp")) {
                StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparator);
                while (tokenizer.hasMoreTokens()) {
                    String token = tokenizer.nextToken();
                    File file = new File(token);
                    if (file.exists()) {
                        fileList.add(file);
                    } else {
                        Message.warn("Skipping extra classpath '" + file
                                + "' as it does not exist.");
                    }
                }
            }
        }
        return fileList;
    }

    private static IvySettings initSettings(CommandLine line, Ivy ivy)
            throws java.text.ParseException, IOException, ParseException {
        IvySettings settings = ivy.getSettings();
        settings.addAllVariables(System.getProperties());
        if (line.hasOption("properties")) {
            settings.addAllVariables(new PropertiesFile(new File(line.getOptionValue("properties")),
                    "additional properties"));
        }
        if (line.hasOption("m2compatible")) {
            settings.setVariable("ivy.default.configuration.m2compatible", "true");
        }

        configureURLHandler(line.getOptionValue("realm", null), line.getOptionValue("host", null),
            line.getOptionValue("username", null), line.getOptionValue("passwd", null));

        String settingsPath = line.getOptionValue("settings", "");
        if ("".equals(settingsPath)) {
            settingsPath = line.getOptionValue("conf", "");
            if (!"".equals(settingsPath)) {
                Message.deprecated("-conf is deprecated, use -settings instead");
            }
        }
        if ("".equals(settingsPath)) {
            ivy.configureDefault();
        } else {
            final URI confUri = getSettingsURI(settingsPath);
            if ("file".equals(confUri.getScheme())) {
                File conffile = new File(confUri);
                if (!conffile.exists()) {
                    throw new IOException("ivy configuration file not found: " + conffile);
                } else if (conffile.isDirectory()) {
                    throw new IOException("ivy configuration file is not a file: " + conffile);
                }
                ivy.configure(conffile);
            } else {
                try {
                    ivy.configure(confUri.toURL());
                } catch (IOException ioe) {
                    throw new IOException("ivy configuration failed to load from: " + settingsPath, ioe);
                }
            }
        }
        return settings;
    }

    private static URI getSettingsURI(String settingsPath) {
        URI settingsUri;
        try {
            settingsUri = new URI(settingsPath);
            if (settingsUri.getScheme() == null) {
                settingsUri = new File(settingsPath).toURI();
            }
        } catch (URISyntaxException badUriEx) {
            return new File(settingsPath).toURI();
        }
        return settingsUri;
    }

    private static void initMessage(CommandLine line, Ivy ivy) {
        if (line.hasOption("debug")) {
            ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_DEBUG));
        } else if (line.hasOption("verbose")) {
            ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_VERBOSE));
        } else if (line.hasOption("warn")) {
            ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_WARN));
        } else if (line.hasOption("error")) {
            ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_ERR));
        } else {
            ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_INFO));
        }
    }

    private static void outputCachePath(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
            String outFile) {
        try {
            StringBuilder buf = new StringBuilder();
            Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
            ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
            XmlReportParser parser = new XmlReportParser();
            for (String conf : confs) {
                String resolveId = ResolveOptions.getDefaultResolveId(md);
                File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
                parser.parse(report);

                all.addAll(Arrays.asList(parser.getArtifactReports()));
            }
            for (ArtifactDownloadReport artifact : all) {
                if (artifact.getLocalFile() != null) {
                    buf.append(artifact.getLocalFile().getCanonicalPath());
                    buf.append(File.pathSeparator);
                }
            }

            PrintWriter writer = new PrintWriter(new FileOutputStream(outFile));
            if (buf.length() > 0) {
                buf.setLength(buf.length() - File.pathSeparator.length());
                writer.println(buf);
            }
            writer.close();
            System.out.println("cachepath output to " + outFile);

        } catch (Exception ex) {
            throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex);
        }
    }

    @SuppressWarnings("resource")
    private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
            List<File> fileList, String mainclass, String[] args) {
        List<URL> urls = new ArrayList<>();

        // Add option cp (extra classpath) urls
        if (fileList != null && fileList.size() > 0) {
            for (File file : fileList) {
                try {
                    urls.add(file.toURI().toURL());
                } catch (MalformedURLException e) {
                    // Should not happen, just ignore.
                }
            }
        }

        try {
            Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
            ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
            XmlReportParser parser = new XmlReportParser();
            for (String conf : confs) {
                String resolveId = ResolveOptions.getDefaultResolveId(md);
                File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
                parser.parse(report);

                all.addAll(Arrays.asList(parser.getArtifactReports()));
            }
            for (ArtifactDownloadReport artifact : all) {
                if (artifact.getLocalFile() != null) {
                    urls.add(artifact.getLocalFile().toURI().toURL());
                }
            }
        } catch (Exception ex) {
            throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex);
        }

        URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
                Main.class.getClassLoader().getParent());

        try {
            Class<?> c = classLoader.loadClass(mainclass);

            Method mainMethod = c.getMethod("main", String[].class);

            Thread.currentThread().setContextClassLoader(classLoader);
            mainMethod.invoke(null, new Object[] {(args == null ? new String[0] : args)});
        } catch (ClassNotFoundException cnfe) {
            throw new RuntimeException("Could not find class: " + mainclass, cnfe);
        } catch (SecurityException | NoSuchMethodException e) {
            throw new RuntimeException("Could not find main method: " + mainclass, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("No permissions to invoke main method: " + mainclass, e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Unexpected exception invoking main method: " + mainclass, e);
        }
    }

    private static void configureURLHandler(String realm, String host, String username,
            String passwd) {
        CredentialsStore.INSTANCE.addCredentials(realm, host, username, passwd);

        URLHandlerDispatcher dispatcher = new URLHandlerDispatcher();
        TimeoutConstrainedURLHandler httpHandler = URLHandlerRegistry.getHttp();
        dispatcher.setDownloader("http", httpHandler);
        dispatcher.setDownloader("https", httpHandler);
        URLHandlerRegistry.setDefault(dispatcher);
    }

    private static void error(String msg) throws ParseException {
        throw new ParseException(msg);
    }

    private static void usage(CommandLineParser parser, boolean showDeprecated) {
        // automatically generate the help statement
        PrintWriter pw = new PrintWriter(System.out);
        parser.printHelp(pw, HELP_WIDTH, "ivy", showDeprecated);
        pw.flush();
    }

    private Main() {
    }
}
