/*
 * Copyright (c) 2017, 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 9999999
 * @summary XXX
 * @modules jdk.compiler/com.sun.tools.javac.api
 */

import com.sun.source.tree.CompilationUnitTree;
import com.sun.tools.javac.api.JavacTaskImpl;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;
import com.sun.source.util.Trees;

public class EnumConstantPositions {
    private final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();

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

    void run() throws IOException {
        String code = "public enum E {\n" +
                      "    A {\n" +
                      "        int i;\n" +
                      "    }\n" +
                      "}\n";

        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, d -> {},
                                                        List.of("-Xjcov"),
                                                        null, Arrays.asList(new MyFileObject(code)));
        Trees trees = Trees.instance(ct);

        Iterable<? extends CompilationUnitTree> units = ct.parse();

        for (CompilationUnitTree cut : units) {
            new TreeScanner<Void, Void>() {
                private long[] currentSpan = new long[] {0, Long.MAX_VALUE};
                @Override
                public Void scan(Tree tree, Void p) {
                    if (tree == null) return null;
                    long[] prevSpan = currentSpan;
                    try {
                        long start = trees.getSourcePositions().getStartPosition(cut, tree);
                        long end = trees.getSourcePositions().getEndPosition(cut, tree);
                        if (end == (-1))
                            return null;
                        if (prevSpan[0] > start || prevSpan[1] < end) {
                            throw new AssertionError("Trees don't embed: enclosing: " + prevSpan[0] + "-" + prevSpan[1] + "; current: " + start + "-" + end);
                        }
                        currentSpan = new long[] {start, end};
                        return super.scan(tree, p);
                    } finally {
                        currentSpan = prevSpan;
                    }
                }
            }.scan(cut, null);
        }
    }

    class MyFileObject extends SimpleJavaFileObject {

        private String text;

        public MyFileObject(String text) {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
            this.text = text;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return text;
        }
    }
}
