/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.bpm.console.server.util;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

/**
 * Creates HTML documention for JAX-RS resource classes.
 *
 * @author Heiko.Braun <heiko.braun@jboss.com>
 */
public class RsDocBuilder
{
  private String webContext;
  private Class[] rootResources;

  public RsDocBuilder(String webContext, Class[] rootResources)
  {
    this.rootResources = rootResources;
    this.webContext = webContext.startsWith("/") ? webContext : "/"+webContext;
  }

  public String getWebContext()
  {
    return webContext;
  }

  public Class[] getRootResources()
  {
    return rootResources;
  }

  private StringBuffer build(Class root)
  {
    Path rootPath = (Path)root.getAnnotation(Path.class);
    RsComment rootComment = (RsComment)root.getAnnotation(RsComment.class);

    List<Representation> representations = new ArrayList<Representation>();

    for(Method m : root.getDeclaredMethods())
    {
      Path resPath = m.getAnnotation(Path.class);
      if(resPath!=null)
      {
        Representation r = new Representation();

        r.path = resPath.value();
        r.httpMethod = m.getAnnotation(GET.class)!=null ? "GET" : "POST"; // currently limited to those
        r.consume = (m.getAnnotation(Consumes.class)!=null) ?
            arrayToString(m.getAnnotation(Consumes.class).value()) : "*/*";
        r.produce = (m.getAnnotation(Produces.class)!=null) ?
            arrayToString(m.getAnnotation(Produces.class).value()) : "*/*";
        representations.add(r);
      }
    }

    StringBuffer sb = new StringBuffer();

    if(rootComment!=null)
    {
      sb.append("<tr>");
      sb.append("<td colspan=5 style='border-bottom:1px solid black;'>");
      sb.append("<b>").append(rootComment.title()).append("</b>").append("<br>");
      sb.append("<i>").append(rootComment.description()).append("</i>");
      sb.append("</td>");
      sb.append("</tr>");
    }

    for(Representation r : representations)
    {
      sb.append("<tr>");
      sb.append("<td>").append(r.httpMethod.toUpperCase()).append("</td>");
      sb.append("<td>").append(buildPath(rootPath.value(),r.path)).append("</td>");
      sb.append("<td>").append("").append("</td>"); // description
      sb.append("<td>").append(r.consume).append("</td>");
      sb.append("<td>").append(r.produce).append("</td>");
      sb.append("</tr>");      
    }

    sb.append("<tr><td colspan=5>&nbsp;</td></tr>");
    
    return sb;
  }

  private String arrayToString(String[] arr)
  {
    StringBuffer sb = new StringBuffer();
    for(int i=0; i<arr.length; i++)
    {
      sb.append(arr[i]);
      if(i<arr.length-1)
        sb.append(",");
    }
    return sb.toString();
  }

  private String buildPath(String root, String resourcePath)
  {
    StringBuffer sb = new StringBuffer();
    sb.append(webContext);
    sb.append("/").append(root).append("/");
    sb.append(resourcePath);
    return sb.toString();
  }

  public StringBuffer build()
  {
    StringBuffer sb = new StringBuffer();
    sb.append("<html>").append("<body style='font-family: sans-serif; font-size:10pt;'>");
    sb.append("<!--").append(" generated by RsDoc at ").append( new Date() ).append(" -->");
    sb.append("<table style='margin-top:10px;' width='100%'>");

    sb.append("<tr>");
    sb.append("<th>").append("Method").append("</th>");
    sb.append("<th>").append("Path").append("</th>");
    sb.append("<th>").append("Description").append("</th>"); // description
    sb.append("<th>").append("Consumes").append("</th>");
    sb.append("<th>").append("Produces").append("</th>");
    sb.append("</tr>");
    
    for(Class c : rootResources)
    {
      sb.append(
          build(c).toString()
      );
    }
    sb.append("</table>");
    sb.append("</body>").append("<html>");
    return sb;

  }

  private class Representation
  {
    String description,title = "";
    String consume,produce = "";
    String path;
    String httpMethod;
  }
}
