import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

import javax.lang.model.element.Element;
import javax.lang.model.element.QualifiedNameable;
import javax.lang.model.util.ElementScanner14;
import javax.lang.model.util.Elements;
import javax.tools.ToolProvider;

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

/**
 * ShowComments class.
 */
public class ShowComments {
    private PrintWriter log;
    private PrintWriter err;

    public static void main(String... args) {
        new ShowComments().run(args);
    }

    ShowComments() {
        log = new PrintWriter(System.out, true);
        err = new PrintWriter(System.err, true);
    }

    void run(String... args) {
        var files = Arrays.stream(args).map(Path::of).toList();

        var comp = ToolProvider.getSystemJavaCompiler();
        var fm = comp.getStandardFileManager(null, null, null);
        var task = ((JavacTool) comp).getTask(err, fm, null,
                List.of("--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"), // allows demo to read itself
                null,
                fm.getJavaFileObjectsFromPaths(files));
        var elements = task.getElements();
        task.addTaskListener(new TaskListener() {
            @Override
            public void started(TaskEvent e) {
                if (e.getKind() == TaskEvent.Kind.ANALYZE) {
                    var te = e.getTypeElement();
                    showCommentScanner.scan(te, elements);
                }
            }
        });
        try {
            task.analyze();
        } catch (IOException e) {
            err.println(e);
        }
    }

    ElementScanner14<Void, Elements> showCommentScanner = new ElementScanner14<>() {
        @Override
        public Void scan(Element e, Elements elements) {
            String comment = elements.getDocComment(e);
            if (comment != null) {
                log.println("# file " + elements.getFileObjectOf(e).getName() + " "
                        + ((e instanceof QualifiedNameable qn) ? qn.getQualifiedName() : e.getSimpleName()));
                log.println("    " + comment.replace(' ', '●').replace('\n', '▲'));
            }
            return super.scan(e, elements);
        }
    };
}