/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.openmeetings.doc;

import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;
import com.sun.tools.doclets.standard.Standard;

public class WebServiceDoclet extends Standard {
	private static final Logger log = Red5LoggerFactory.getLogger(WebServiceDoclet.class, webAppRootKey);
	
	static final String baseTemplatePath = "xdocs";
	static final String basePath = "dist/red5/webapps/openmeetings/docs";
	static final String templateName = "ApiMethodsTemplate.vm";
	static final String templateNameIndex = "ApiClassesTemplate.vm";

	public static boolean start(RootDoc root) {

		try {
			
			Velocity.init();
			out("Start WebServiceDoclet templateNameNew " + templateName);
			
			ArrayList<Map<String,String>> classesParsed = new ArrayList<Map<String,String>>(root.classes().length);
			
			// iterate over all classes.
			ClassDoc[] classes = root.classes();
			for (int i = 0; i < classes.length; i++) {
				// iterate over all methods and print their names.
				
				VelocityContext vContext = new VelocityContext();
				vContext.put("className", classes[i].name());
				vContext.put("classComment", classes[i].commentText());
				
				String defaultOutputName = classes[i].name();
				for (Tag tag : classes[i].tags()) {
					if (tag.name().equals("@webservice")) {
						defaultOutputName = tag.text();
					}
				}
				
				vContext.put("webServiceName", defaultOutputName);
				
				HashMap<String,String> classItem = new HashMap<String,String>();
				classItem.put("name",defaultOutputName);
				classItem.put("comment",classes[i].commentText());
				classesParsed.add(classItem);
				
				vContext.put("methods", classes[i].methods());
				
				FileWriter strWriter = new FileWriter(basePath
						+ File.separatorChar + defaultOutputName + ".html");

				Velocity.mergeTemplate(baseTemplatePath + File.separatorChar
						+ templateName, "UTF-8", vContext, strWriter);
				
				strWriter.flush();
				strWriter.close();

			}
			
			
			VelocityContext vIndexContext = new VelocityContext();
			vIndexContext.put("classes", classesParsed);
			
			FileWriter newFileIndexWriter = new FileWriter(basePath
					+ File.separatorChar + "WebserviceIndex.html");

			Velocity.mergeTemplate(baseTemplatePath + File.separatorChar
					+ templateNameIndex, "UTF-8", vIndexContext, newFileIndexWriter);
			
			newFileIndexWriter.flush();
			newFileIndexWriter.close();
			

		} catch (Exception err) {
			log.error("[start]", err);
		}

		// No error processing done, simply return true.
		return true;
	}

	private static void out(String msg) {
		System.out.println(msg);
	}

}
