/*
 * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 6920317
 * @summary package-info.java file has to be specified on the javac cmdline, else it will not be avail
 * @library /tools/javac/lib
 * @modules jdk.compiler
 */

import java.io.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import javax.tools.*;

/**
 * The test exercises different ways of providing annotations for a package.
 * Each way provides an annotation with a unique argument. For each test
 * case, the test verifies that the annotation with the correct argument is
 * found by the compiler.
 */
public class T6920317 {
    public static void main(String... args) throws Exception {
        new T6920317().run(args);
    }

    // Used to describe properties of files to be put on command line, source path, class path
    enum Kind {
        /** File is not used. */
        NONE,
        /** File is used. */
        OLD,
        /** Only applies to files on classpath/sourcepath, when there is another file on the
         *  other path of type OLD, in which case, this file must be newer than the other one. */
        NEW,
        /** Only applies to files on classpath/sourcepath, when there is no file in any other
         *  location, in which case, this file will be generated by the annotation processor. */
        GEN
    }

    void run(String... args) throws Exception {
        // if no args given, all test cases are run
        // if args given, they indicate the test cases to be run
        for (int i = 0; i < args.length; i++) {
            tests.add(Integer.valueOf(args[i]));
        }

        setup();

        // Run tests for all combinations of files on command line, source path and class path.
        // Invalid combinations are skipped in the test method
        for (Kind cmdLine: EnumSet.of(Kind.NONE, Kind.OLD)) {
            for (Kind srcPath: Kind.values()) {
                for (Kind clsPath: Kind.values()) {
                    try {
                        test(cmdLine, srcPath, clsPath);
                    } catch (Exception e) {
                        e.printStackTrace();
                        error("Exception " + e);
                        // uncomment to stop on first failed test case
                        // throw e;
                    }
                }
            }
        }

        if (errors > 0)
            throw new Exception(errors + " errors occurred");
    }

    /** One time setup for files and directories to be used in the various test cases. */
    void setup() throws Exception {
        // Annotation used in test cases to annotate package. This file is
        // given on the command line in test cases.
        test_java = writeFile("Test.java", "package p; @interface Test { String value(); }");
        // Compile the annotation for use later in setup
        File tmpClasses = new File("tmp.classes");
        compile(tmpClasses, new String[] { }, test_java);

        // package-info file to use on the command line when requied
        cl_pkgInfo_java = writeFile("cl/p/package-info.java", "@Test(\"CL\") package p;");

        // source path containing package-info
        sp_old = new File("src.old");
        writeFile("src.old/p/package-info.java", "@Test(\"SP_OLD\") package p;");

        // class path containing package-info
        cp_old = new File("classes.old");
        compile(cp_old, new String[] { "-classpath", tmpClasses.getPath() },
                writeFile("tmp.old/p/package-info.java", "@Test(\"CP_OLD\") package p;"));

        // source path containing package-info which is newer than the one in cp-old
        sp_new = new File("src.new");
        File old_class = new File(cp_old, "p/package-info.class");
        writeFile("src.new/p/package-info.java", "@Test(\"SP_NEW\") package p;", old_class);

        // class path containing package-info which is newer than the one in sp-old
        cp_new = new File("classes.new");
        File old_java = new File(sp_old, "p/package-info.java");
        compile(cp_new, new String[] { "-classpath", tmpClasses.getPath() },
                writeFile("tmp.new/p/package-info.java", "@Test(\"CP_NEW\") package p;", old_java));

        // directory containing package-info.java to be "generated" later by annotation processor
        sp_gen = new File("src.gen");
        writeFile("src.gen/p/package-info.java", "@Test(\"SP_GEN\") package p;");

        // directory containing package-info.class to be "generated" later by annotation processor
        cp_gen = new File("classes.gen");
        compile(cp_gen, new String[] { "-classpath", tmpClasses.getPath() },
                writeFile("tmp.gen/p/package-info.java", "@Test(\"CP_GEN\") package p;"));
    }

    void test(Kind cl, Kind sp, Kind cp) throws Exception {
        if (skip(cl, sp, cp))
            return;

        ++count;
        // if test cases specified, skip this test case if not selected
        if (tests.size() > 0 && !tests.contains(count))
            return;

        System.err.println("Test " + count + " cl:" + cl + " sp:" + sp + " cp:" + cp);

        // test specific tmp directory
        File test_tmp = new File("tmp.test" + count);
        test_tmp.mkdirs();

        // build up list of options and files to be compiled
        List<String> opts = new ArrayList<String>();
        List<File> files = new ArrayList<File>();

        // expected value for annotation
        String expect = null;

        opts.add("-processorpath");
        String testClasses = System.getProperty("test.classes");
        String testClassPath = System.getProperty("test.class.path", testClasses);
        opts.add(testClassPath);
        opts.add("-processor");
        opts.add(Processor.class.getName());
        opts.add("-proc:only");
        opts.add("-d");
        opts.add(test_tmp.getPath());
        //opts.add("-verbose");
        files.add(test_java);

        /*
         * Analyze each of cl, cp, sp, building up the options and files to
         * be compiled, and determining the expected outcome fo the test case.
         */

        // command line file: either omitted or given
        if (cl == Kind.OLD) {
            files.add(cl_pkgInfo_java);
            // command line files always supercede files on paths
            expect = "CL";
        }

        // source path:
        switch (sp) {
        case NONE:
            break;

        case OLD:
            opts.add("-sourcepath");
            opts.add(sp_old.getPath());
            if (expect == null && cp == Kind.NONE) {
                assert cl == Kind.NONE && cp == Kind.NONE;
                expect = "SP_OLD";
            }
            break;

        case NEW:
            opts.add("-sourcepath");
            opts.add(sp_new.getPath());
            if (expect == null) {
                assert cl == Kind.NONE && cp == Kind.OLD;
                expect = "SP_NEW";
            }
            break;

        case GEN:
            opts.add("-Agen=" + new File(sp_gen, "p/package-info.java"));
            assert cl == Kind.NONE && cp == Kind.NONE;
            expect = "SP_GEN";
            break;
        }

        // class path:
        switch (cp) {
        case NONE:
            break;

        case OLD:
            opts.add("-classpath");
            opts.add(cp_old.getPath());
            if (expect == null && sp == Kind.NONE) {
                assert cl == Kind.NONE && sp == Kind.NONE;
                expect = "CP_OLD";
            }
            break;

        case NEW:
            opts.add("-classpath");
            opts.add(cp_new.getPath());
            if (expect == null) {
                assert cl == Kind.NONE && sp == Kind.OLD;
                expect = "CP_NEW";
            }
            break;

        case GEN:
            opts.add("-Agen=" + new File(cp_gen, "p/package-info.class"));
            assert cl == Kind.NONE && sp == Kind.NONE;
            expect = "CP_GEN";
            break;
        }

        // pass expected value to annotation processor
        assert expect != null;
        opts.add("-Aexpect=" + expect);

        // compile the files with the options that have been built up
        compile(opts, files);
    }

    /**
     * Return true if this combination of parameters does not identify a useful test case.
     */
    boolean skip(Kind cl, Kind sp, Kind cp) {
        // skip if no package files required
        if (cl == Kind.NONE && sp == Kind.NONE && cp == Kind.NONE)
            return true;

        // skip if both sp and sp are OLD, since results may be indeterminate
        if (sp == Kind.OLD && cp == Kind.OLD)
            return true;

        // skip if sp or cp is NEW but the other is not OLD
        if ((sp == Kind.NEW && cp != Kind.OLD) || (cp == Kind.NEW && sp != Kind.OLD))
            return true;

        // only use GEN if no other package-info files present
        if (sp == Kind.GEN && !(cl == Kind.NONE && cp == Kind.NONE) ||
            cp == Kind.GEN && !(cl == Kind.NONE && sp == Kind.NONE)) {
            return true;
        }

        // remaining combinations are valid
        return false;
    }

    /** Write a file with a given body. */
    File writeFile(String path, String body) throws Exception {
        File f = new File(path);
        if (f.getParentFile() != null)
            f.getParentFile().mkdirs();
        Writer out = new FileWriter(path);
        try {
            out.write(body);
        } finally {
            out.close();
        }
        return f;
    }

    /** Write a file with a given body, ensuring that the file is newer than a reference file. */
    File writeFile(String path, String body, File ref) throws Exception {
        for (int i = 0; i < 5; i++) {
            File f = writeFile(path, body);
            if (f.lastModified() > ref.lastModified())
                return f;
            Thread.sleep(2000);
        }
        throw new Exception("cannot create file " + path + " newer than " + ref);
    }

    /** Compile a file to a given directory, with options provided. */
    void compile(File dir, String[] opts, File src) throws Exception {
        dir.mkdirs();
        List<String> opts2 = new ArrayList<String>();
        opts2.addAll(Arrays.asList("-d", dir.getPath()));
        opts2.addAll(Arrays.asList(opts));
        compile(opts2, Collections.singletonList(src));
    }

    /** Compile files with options provided. */
    void compile(List<String> opts, List<File> files) throws Exception {
        System.err.println("javac: " + opts + " " + files);
        List<String> args = new ArrayList<String>();
        args.addAll(opts);
        for (File f: files)
            args.add(f.getPath());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
        pw.flush();
        if (sw.getBuffer().length() > 0)
            System.err.println(sw.toString());
        if (rc != 0)
            throw new Exception("compilation failed: rc=" + rc);
    }

    /** Report an error. */
    void error(String msg) {
        System.err.println("Error: " + msg);
        errors++;
    }

    /** Test case counter. */
    int count;

    /** Number of errors found. */
    int errors;

    /** Optional set of test cases to be run; empty implies all test cases. */
    Set<Integer> tests = new HashSet<Integer>();

    /*  Files created by setup. */
    File test_java;
    File sp_old;
    File sp_new;
    File sp_gen;
    File cp_old;
    File cp_new;
    File cp_gen;
    File cl_pkgInfo_java;

    /** Annotation processor used to verify the expected value for the
        package annotations found by javac. */
    @SupportedOptions({ "gen", "expect" })
    public static class Processor extends JavacTestingAbstractProcessor {
        public boolean process(Set<? extends TypeElement> annots, RoundEnvironment renv) {
            round++;
            System.err.println("Round " + round + " annots:" + annots + " rootElems:" + renv.getRootElements());

            // if this is the first round and the gen option is given, use the filer to create
            // a copy of the file specified by the gen option.
            String gen = getOption("gen");
            if (round == 1 && gen != null) {
                try {
                    Filer filer = processingEnv.getFiler();
                    JavaFileObject f;
                    if (gen.endsWith(".java"))
                        f = filer.createSourceFile("p.package-info");
                    else
                        f = filer.createClassFile("p.package-info");
                    System.err.println("copy " + gen + " to " + f.getName());
                    write(f, read(new File(gen)));
                } catch (IOException e) {
                    error("Cannot create package-info file: " + e);
                }
            }

            // if annotation processing is complete, verify the package annotation
            // found by the compiler.
            if (renv.processingOver()) {
                System.err.println("final round");
                Elements eu = processingEnv.getElementUtils();
                TypeElement te = eu.getTypeElement("p.Test");
                PackageElement pe = eu.getPackageOf(te);
                System.err.println("final: te:" + te + " pe:" + pe);
                List<? extends AnnotationMirror> annos = pe.getAnnotationMirrors();
                System.err.println("final: annos:" + annos);
                if (annos.size() == 1) {
                    String expect = "@" + te + "(\"" + getOption("expect") + "\")";
                    String actual = annos.get(0).toString();
                    checkEqual("package annotations", actual, expect);
                } else {
                    error("Wrong number of annotations found: (" + annos.size() + ") " + annos);
                }
            }

            return true;
        }

        /** Get an option given to the annotation processor. */
        String getOption(String name) {
            return processingEnv.getOptions().get(name);
        }

        /** Read a file. */
        byte[] read(File file) {
            byte[] bytes = new byte[(int) file.length()];
            try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
                in.readFully(bytes);
            } catch (IOException e) {
                error("Error reading file: " + e);
            }
            return  bytes;
        }

        /** Write a file. */
        void write(JavaFileObject file, byte[] bytes) {
            try (OutputStream out = file.openOutputStream()) {
                out.write(bytes, 0, bytes.length);
            } catch (IOException e) {
                error("Error writing file: " + e);
            }
        }

        /** Check two strings are equal, and report an error if they are not. */
        private void checkEqual(String label, String actual, String expect) {
            if (!actual.equals(expect)) {
                error("Unexpected value for " + label + "; actual=" + actual + ", expected=" + expect);
            }
        }

        /** Report an error to the annotation processing system. */
        void error(String msg) {
            Messager messager = processingEnv.getMessager();
            messager.printError(msg);
        }

        int round;
    }
}
