/*
 * Copyright (c) 2011, 2012, 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     7093891
 * @summary support multiple task listeners
 */

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.JavacTool;

public class TestSimpleAddRemove {
    enum AddKind {
        SET_IN_TASK,
        ADD_IN_TASK,
        ADD_IN_PROCESSOR,
        ADD_IN_LISTENER;
    }

    enum RemoveKind {
        REMOVE_IN_TASK,
        REMOVE_IN_PROCESSOR,
        REMOVE_IN_LISTENER,
    }

    enum CompileKind {
        CALL {
            void run(JavacTask t) {
                if (!t.call()) throw new Error("compilation failed");
            }
        },
        GENERATE {
            void run(JavacTask t) throws IOException {
                t.generate();
            }
        };
        abstract void run(JavacTask t) throws IOException;
    }

    static class EventKindCounter extends EnumMap<TaskEvent.Kind, EventKindCounter.Count> {
        static class Count {
            int started;
            int finished;

            @Override
            public String toString() {
                return started + ":" + finished;
            }
        }

        EventKindCounter() {
            super(TaskEvent.Kind.class);
        }

        void inc(TaskEvent.Kind k, boolean started) {
            Count c = get(k);
            if (c == null)
                put(k, c = new Count());

            if (started)
                c.started++;
            else
                c.finished++;
        }
    }

    static class TestListener implements TaskListener {
        EventKindCounter counter;

        TestListener(EventKindCounter c) {
            counter = c;
        }

        public void started(TaskEvent e) {
            counter.inc(e.getKind(), true);
        }

        public void finished(TaskEvent e) {
            counter.inc(e.getKind(), false);
        }
    }

    static void addInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
        task.addTaskListener(new TaskListener() {
            public void started(TaskEvent e) {
                if (e.getKind() == kind) {
                    task.addTaskListener(listener);
                    task.removeTaskListener(this);
                }
            }

            public void finished(TaskEvent e) { }
        });
    }

    static void removeInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
        task.addTaskListener(new TaskListener() {
            public void started(TaskEvent e) {
                if (e.getKind() == kind) {
                    task.removeTaskListener(listener);
                    task.removeTaskListener(this);
                }
            }

            public void finished(TaskEvent e) { }
        });
    }

    @SupportedAnnotationTypes("*")
    class TestProcessor extends AbstractProcessor {
        AddKind ak;
        RemoveKind rk;
        TaskListener listener;

        TestProcessor(AddKind ak, RemoveKind rk, TaskListener listener) {
            this.ak = ak;
            this.rk = rk;
            this.listener = listener;
        }

        int round = 0;

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//            System.err.println("TestProcessor.process " + roundEnv);
            JavacTask task = JavacTask.instance(processingEnv);
            if (++round == 1) {
                switch (ak) {
                    case ADD_IN_PROCESSOR:
                        task.addTaskListener(listener);
                        break;
                    case ADD_IN_LISTENER:
                        addInListener(task, TaskEvent.Kind.ANALYZE, listener);
                        break;
                }
            } else if (roundEnv.processingOver()) {
                switch (rk) {
                    case REMOVE_IN_PROCESSOR:
                        task.removeTaskListener(listener);
                        break;
                    case REMOVE_IN_LISTENER:
                        removeInListener(task, TaskEvent.Kind.GENERATE, listener);
                        break;
                }
            }
            return true;
        }
    }

    static class TestSource extends SimpleJavaFileObject {
        public TestSource() {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return "class Test { }";
        }
    }

    public static void main(String... args) throws Exception {
        new TestSimpleAddRemove().run();
    }

    JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);

    void run() throws Exception {
        for (CompileKind ck: CompileKind.values()) {
            for (AddKind ak: AddKind.values()) {
                for (RemoveKind rk: RemoveKind.values()) {
                    test(ck, ak, rk);
                }
            }
        }
        if (errors > 0)
            throw new Exception(errors + " errors occurred");
    }

    void test(CompileKind ck, AddKind ak, RemoveKind rk) throws IOException {
        System.err.println("Test: " + ck + " " + ak + " " + rk);

        File tmpDir = new File(ck + "-" + ak + "-" + rk);
        tmpDir.mkdirs();
        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir));

        List<String> options = new ArrayList<String>();
        Iterable<? extends JavaFileObject> files = Arrays.asList(new TestSource());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        JavacTask task = tool.getTask(pw, fm, null, options, null, files);

        EventKindCounter ec = new EventKindCounter();
        TaskListener listener = new TestListener(ec);
        boolean needProcessor = false;

        switch (ak) {
            case SET_IN_TASK:
                task.setTaskListener(listener);
                break;
            case ADD_IN_TASK:
                task.addTaskListener(listener);
                break;
            case ADD_IN_PROCESSOR:
            case ADD_IN_LISTENER:
                needProcessor = true;
        }

        switch (rk) {
            case REMOVE_IN_TASK:
                task.removeTaskListener(listener);
                break;
            case REMOVE_IN_PROCESSOR:
            case REMOVE_IN_LISTENER:
                needProcessor = true;
        }

        if (needProcessor)
            task.setProcessors(Arrays.asList(new TestProcessor(ak, rk, listener)));

        ck.run(task);
        System.err.println(ec);

        check(ck, ak, rk, ec);

        System.err.println();
    }

    void check(CompileKind ck, AddKind ak, RemoveKind rk, EventKindCounter ec) {
        // All results should be independent of ck, so we can ignore that

        // Quick way to compare expected values of ec, by comparing ec.toString()
        String expect = ec.toString();
        String found;

        switch (ak) {
            // Add/set in task should record all events until the listener is removed
            case SET_IN_TASK:
            case ADD_IN_TASK:
                switch (rk) {
                    case REMOVE_IN_TASK:
                        // Remove will succeed, meaning no events will be recorded
                        found = "{}";
                        break;
                    case REMOVE_IN_PROCESSOR:
                        found = "{PARSE=1:1, ENTER=2:2, ANNOTATION_PROCESSING=1:0, ANNOTATION_PROCESSING_ROUND=2:1}";
                        break;
                    case REMOVE_IN_LISTENER:
                        found = "{PARSE=1:1, ENTER=3:3, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=1:1, ANNOTATION_PROCESSING_ROUND=2:2}";
                        break;
                    default:
                        throw new IllegalStateException();
                }
                break;

            // "Add in processor" should skip initial PARSE/ENTER events
            case ADD_IN_PROCESSOR:
                switch (rk) {
                    // Remove will fail (too early), so events to end will be recorded
                    case REMOVE_IN_TASK:
                        found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:1, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
                        break;
                    case REMOVE_IN_PROCESSOR:
                        found = "{ENTER=1:1, ANNOTATION_PROCESSING_ROUND=1:1}";
                        break;
                    case REMOVE_IN_LISTENER:
                        found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
                        break;
                    default:
                        throw new IllegalStateException();
                }
                break;

            // "Add in listener" will occur during "ANALYSE.started" event
            case ADD_IN_LISTENER:
                switch (rk) {
                    // Remove will fail (too early, so events to end will be recorded
                    case REMOVE_IN_TASK:
                    case REMOVE_IN_PROCESSOR:
                        found = "{ANALYZE=0:1, GENERATE=1:1}";
                        break;
                    // Remove will succeed during "GENERATE.finished" event
                    case REMOVE_IN_LISTENER:
                        found = "{ANALYZE=0:1, GENERATE=1:0}";
                        break;
                    default:
                        throw new IllegalStateException();
                }
                break;
            default:
                throw new IllegalStateException();
        }

        if (!found.equals(expect)) {
            System.err.println("Expected: " + expect);
            System.err.println("   Found: " + found);
            error("unexpected value found");
        }
    }

    int errors;

    void error(String message) {
        System.err.println("Error: " + message);
        errors++;
    }
}
