/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed 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
 *
 *     http://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.opengion.fukurou.taglet;


import jdk.javadoc.doclet.Doclet  ;
import jdk.javadoc.doclet.Reporter ;
import java.util.Locale ;
import com.sun.source.doctree.DocCommentTree  ;
import com.sun.source.util.DocTrees  ;
import javax.lang.model.element.Element   ;
import jdk.javadoc.doclet.DocletEnvironment    ;
import javax.lang.model.SourceVersion    ;
import javax.tools.Diagnostic.Kind    ;
import javax.lang.model.util.ElementFilter    ;
import javax.lang.model.element.TypeElement;

import java.util.Set;
import java.util.List;
import java.util.HashSet;
import java.util.Arrays;

import java.io.IOException;

/**
 * ソースコメントから、パラメータ情報を取り出す Doclet クラスです。
 * og.paramLevel タグと og.cryptography タグを切り出します。
 * これらは、ｼｽﾃﾑパラメータとしてGE12ﾃｰﾌﾞﾙに設定される値をクラスより抽出する
 * のに使用します。
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class Example implements Doclet {
   Reporter reporter;
   @Override
   public void init(Locale locale, Reporter reporter) {
	   reporter.print(Kind.NOTE, "Doclet using locale: " + locale);
	   this.reporter = reporter;
   }

   public void printElement(DocTrees trees, Element e) {
	   DocCommentTree docCommentTree = trees.getDocCommentTree(e);
	   if (docCommentTree != null) {
		   System.out.println("Element (" + e.getKind() + ": "
				   + e + ") has the following comments:");
		   System.out.println("Entire body: " + docCommentTree.getFullBody());
		   System.out.println("Block tags: " + docCommentTree.getBlockTags());
	   }
   }

   @Override
   public boolean run(DocletEnvironment docEnv) {
	   reporter.print(Kind.NOTE, "overviewfile: " + overviewfile);
	   // get the DocTrees utility class to access document comments
	   DocTrees docTrees = docEnv.getDocTrees();

	   // location of an element in the same directory as overview.html
	   try {
		   Element e = ElementFilter.typesIn(docEnv.getSpecifiedElements()).iterator().next();
		   DocCommentTree docCommentTree
				   = docTrees.getDocCommentTree(e, overviewfile);
		   if (docCommentTree != null) {
			   System.out.println("Overview html: " + docCommentTree.getFullBody());
		   }
	   } catch (IOException missing) {
		   reporter.print(Kind.ERROR, "No overview.html found.");
	   }

	   for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
		   System.out.println(t.getKind() + ":" + t);
		   for (Element e : t.getEnclosedElements()) {
			   printElement(docTrees, e);
		   }
	   }
	   return true;
   }

   @Override
   public String getName() {
	   return "Example";
   }

   private String overviewfile;

   @Override
   public Set<? extends Option> getSupportedOptions() {
	   Option[] options = {
		   new Option() {
			   private final List<String> someOption = Arrays.asList(
					   "-overviewfile",
					   "--overview-file",
					   "-o"
			   );

			   @Override
			   public int getArgumentCount() {
				   return 1;
			   }

			   @Override
			   public String getDescription() {
				   return "an option with aliases";
			   }

			   @Override
			   public Option.Kind getKind() {
				   return Option.Kind.STANDARD;
			   }

			   @Override
			   public List<String> getNames() {
				   return someOption;
			   }

			   @Override
			   public String getParameters() {
				   return "file";
			   }

			   @Override
			   public boolean process(String opt, List<String> arguments) {
				   overviewfile = arguments.get(0);
				   return true;
			   }
		   }
	   };
	   return new HashSet<>(Arrays.asList(options));
   }

   @Override
   public SourceVersion getSupportedSourceVersion() {
	   // support the latest release
	   return SourceVersion.latest();
   }
}
