package org.codehaus.groovy.tools

import groovy.xml.StreamingMarkupBuilder

import java.io.File

import com.thoughtworks.qdox.JavaDocBuilder
import com.thoughtworks.qdox.model.JavaSource
import com.thoughtworks.qdox.model.JavaClass
import com.thoughtworks.qdox.model.JavaMethod
import com.thoughtworks.qdox.model.JavaParameter
import com.thoughtworks.qdox.model.Type
import java.util.*;


/**
 * Generate documentation about the methods provided by the Groovy Development Kit
 * enhancing the standard JDK classes.
 *
 * @author Guillaume Laforge, John Wilson
 */
class DocGenerator
{
	File           file
	File           outputFile
	JavaDocBuilder builder

	DocGenerator(File fileToParse, File outputFile)
	{
		this.file       = fileToParse
		this.outputFile = outputFile
	}

	/**
	 * Parse the DefaultGroovyMethods class to build a graph representing the structure of the class,
	 * with its methods, javadoc comments and tags.
	 */
	private void parse()
	{
		def reader  = file.newReader()
		builder = new JavaDocBuilder()

		builder.addSource(reader)
	}

	/**
	 * Builds an HTML page from the structure of DefaultGroovyMethods.
	 */
		
		def generate() {
			parse()
			
			def sources = builder.getSources()

			def firstSource = sources[0]
			def classes = firstSource.getClasses()
			def groovyMeth = classes[0]
	
			// categorize all groovy methods per core JDK class to which it applies
			def jdkEnhancedClasses = [:]
			def methods = groovyMeth.getMethods()
			
            def start = System.currentTimeMillis();
			for (method in methods) {
				if (method.isPublic() && method.isStatic()) {
					def parameters = method.getParameters()
					def jdkClass = parameters[0].getType().toString()

					if (jdkEnhancedClasses.containsKey(jdkClass)) {
					    List l = jdkEnhancedClasses[jdkClass];
						l.add(method)
				    }
					else
						jdkEnhancedClasses[jdkClass] = [method]
				}
			}
            //start = System.currentTimeMillis();
	        println " added classes in ${System.currentTimeMillis() - start} ms"

			def headElement = { head {
								mkp.comment 'generated by Groovy using Streaming Markup'
								title 'GDK : Groovy methods'
								style(['type':'text/css'], '   @import url("./style/maven-base.css"); ')
								style(['type':'text/css'], '   @import url("http://codehaus.org/codehaus-style.css"); ')
							}
						  }
							
			def sortedClasses = new TreeSet(jdkEnhancedClasses.keySet())
							
			def ind = 0
			def cellsInRow = 4
			// Split sortedClasses into list of 4-element lists
			def rowList = sortedClasses.inject([]) { list, item ->
				if (ind++ % cellsInRow == 0)
					list << [item]
				else
					list[-1] << item
				return list
			}

			def classLinks = { mkp.yield {
					def classCounter = 0
					table(width:'100%') {
						tr {
							th(colspan:"${cellsInRow}", "Groovy JDK classes")
						}
						for (row in rowList) {
							if (row.size() < cellsInRow) {
								(cellsInRow - row.size()).times { row << "" }
							}
							tr {
								for (className in row) {
									td(width:'25%') {
										a(href:"#cls${classCounter}", "${className}")
									}
									classCounter++;            	    				
								}
							}
						}
					}
				}
			}

			def summary = { mkp.yield {
					            def counter = 0
								def classCounter = 0
					
								// lets iterate in sorted class name order
								for (String className in sortedClasses) {
					
									p { a(name:"cls${classCounter}") }
									b className
									classCounter++
					
									def listOfMethods = jdkEnhancedClasses[className]
									listOfMethods.sort{ it.name }
									
									table(width:'100%') {
										for (JavaMethod meth in listOfMethods) {
						                    counter++
						                    
						                    tr {
						                    	td(width:'30%') {
						                    		mkp.yield getReturnType(meth)
						                    	}
						                    	td(width:'70%') {
						                    		a(href:"#meth${counter}") { 
						                    			mkp.yield meth.getName()
						                    		}
						                    		mkp.yield "(${getParametersDecl(meth)})"
						                    	}
						                    }
										}
									}
								}
							}
						}
								
			def details = { mkp.yield {
								def counter = 0
								
								for (className in sortedClasses) {
					
									h2 className
					
									def listOfMethods = jdkEnhancedClasses[className]
									listOfMethods.sort{ it.name }
									
									for (JavaMethod meth in listOfMethods) {
					                    counter++

					                    a(name:"meth${counter}")
					                    
					                    p {
					                    	b "${getReturnType(meth)} ${meth.getName()}(${getParametersDecl(meth)})"
					                    }
					                    
				                    	ul {
				                    		//
				                    		// Java comments can contain markup - pass it through as is
				                    		//
				                   			mkp.yieldUnescaped "${getComment(meth)}  "
				                   			
					                    	ul {
												def params = meth.getTags()
												def count = 0
												
												for (param in params) {
													if (count++ != 0 && param.getName() != "throws" && param.getName() != "return") {
														li "${param.getName()} ${param.getValue()}"
													}
												 }

												def returnType = getReturnType(meth)
	
												if (returnType != "") {
												    if (returnType != "void") {
													    li {
													    	b "returns"
															mkp.yield ": ${returnType}"
															    	
													        def returnTag = meth.getTagByName("return")
													                
													        if (returnTag != null) {
													        	mkp.yield " - "
													        	i returnTag.getValue()
															}
														}
													}
													
													def exceptions = meth.getExceptions()
													
													for (ex in exceptions) {
														if (ex != null) {
															li {
																b "throws"
																mkp.yield ": ${ex}"
	
																def exMsg = meth.getTagByName("throws")
																
																if (exMsg != null) {
																	mkp.yield " - "
																	i exMsg.getValue()
																}
															}
														}
													}
												}
											}
					                    }
									}
								}
					  		}
					  	}
					  				
			def bodyElement = { body {
								h1 'Groovy JDK methods'
								p 'New methods added to the JDK to make it more groovy.'
								mkp.yield classLinks
								mkp.yield summary
								mkp.yield details
							 }
						   }
					
			 outputFile.getParentFile().mkdirs()
			 outputFile.newPrintWriter() << new StreamingMarkupBuilder().bind{ html {
																						mkp.yield headElement
																						mkp.yield bodyElement
																					 }
																			  }
		}

		/**
	 	* Retrieves a String representing the return type
	 	*/
		private getReturnType(method)
		{
		    def returnType = method.getReturns()
		    
		    if (returnType != null) {
		    	    return returnType.toString()
		    } else {
		    	    return ""
		    }
		}

		/**
		 * Retrieve a String representing the declaration of the parameters of the method passed as parameter.
		 *
		 * @param method a method
		 * @return the declaration of the method (long version)
		 */
		private getParametersDecl(method)
		{
			getParameters(method).collect{ "${it.getType()} ${it.getName()}" }.join(", ")
		}

		/**
		 * Retrieve the parameters of the method.
		 *
		 * @param method a method
		 * @return a list of parameters without the first one
		 */
		private getParameters(method)
		{
		    if (method.getParameters().size() > 1)
			    return method.getParameters().toList()[1..-1]
			else
			    return []
		}

		/**
		 * Retrieve the JavaDoc comment associated with the method passed as parameter.
		 *
		 * @param method a method
		 * @return the JavaDoc comment associated with this method
		 */
		private getComment(method)
		{
			def ans = method.getComment()
			if (ans == null) return ""
			return ans
		}

    /**
     * Main entry point.
     */
    static void main(args)
    {
        def defaultGroovyMethodSource =
            //new File("D:/cvs-groovy/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java")
            new File("src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java")
        def outFileName =
            //new File("D:/cvs-groovy/groovy/groovy-core/target/html/groovy-jdk.html")
            new File("target/html/groovy-jdk.html")

        def start = System.currentTimeMillis();

        def docGen = new DocGenerator(defaultGroovyMethodSource, outFileName)
        docGen.generate()

        def end = System.currentTimeMillis();

        println "Done. in ${end - start} millis"

    }
}
