package org.jfox.framework.management.http;

import java.util.Arrays;
import java.util.Properties;

import org.jfox.framework.ComponentMeta;
import org.jfox.framework.ComponentName;
import org.jfox.framework.Registry;
import org.jfox.framework.extra.Managable;
import org.jfox.framework.extra.ManagementInfo;
import org.jfox.framework.extra.ManagementOperationInfo;

/**
 * @author <a href="mailto:yangyong@ufsoft.com.cn">Young Yang</a>
 */

public class ViewComponentCommand implements Command {

    public String doGet(Registry registry, Properties queryMap) throws Exception {
        String compName = queryMap.getProperty("compname");
        ComponentName name = ComponentName.parseString(compName, registry.getClassLoaderRepository());
        ComponentMeta meta = registry.getComponentMeta(name);

        StringBuffer sb = new StringBuffer();
        sb.append(PageUtil.head("component view"));
        sb.append(PageUtil.banner("Component View"));

        sb.append(mxInfoTable(meta));
        sb.append(operTable(meta));
        sb.append(PageUtil.foot());
        return sb.toString();
    }

    private static String mxInfoTable(ComponentMeta meta) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("<table width=\"750\" align=\"center\">\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Component Name: </b></td><td>")
                .append(meta.getComponentName().toString())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Module: </b></td><td>")
                .append(meta.getModule())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Description: </b></td><td>")
                .append(meta.getDescription())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Component Factory: </b></td><td>")
                .append(meta.getComponentFactory())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Singleton: </b></td><td>")
                .append(meta.isSingleton());
        if(meta.isSingleton()) {
            sb.append("&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"?action=InstanceComponent&compname=" + meta.getComponentName() + "\">instance it</a>");
        }
        sb.append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Type Singleton: </b></td><td>")
                .append(meta.isTypeSingleton())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Priority: </b></td><td>")
                .append(meta.getPriority())
                .append("</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td width=\"180\" align=\"right\"><b>Reference Components: </b></td><td>")
                .append(Arrays.asList(meta.getRefComponentNames()))
                .append("</td>\n" +
                "  </tr>\n" +

                "\n" +
                "</table><br>\n" +
                "");
        return sb.toString();

    }

    private static String operTable(ComponentMeta meta) throws Exception {
        StringBuffer sb = new StringBuffer();
        ManagementInfo minfo = meta.getManagementInfo();
        if(minfo == null) {
            sb.append("<table width=\"760\" align=\"center\" border=\"1\" style=\"border-collapse: collapse\" bordercolor=\"#000000\">\n" +
                    "  <tr>\n" +
                    "    <td align=\"center\">can't get management operation info, maybe because of<font color=\"red\">");
            if(!Managable.class.isAssignableFrom(meta.getComponentImplementation())) {
                sb.append("<br>the component is not a managable component\n");
            }
            else if(!meta.isSingleton()) {
                sb.append("<br>component is not instance singleton</td>\n");
            }
            else {
                sb.append("<br>component not instance yet</font>\n");
            }
        }
        else {
            sb.append("<table width=\"760\" align=\"center\" border=\"1\" style=\"border-collapse: collapse\" bordercolor=\"#000000\">\n" +
                    "  <tr>\n" +
                    "    <td align=\"center\"><b>Operation</b></td><td width=140><b>Value / Parameter</b></td><td width=150><b>Invoke</b></td>\n" +
                    "  </tr>\n" +
                    "");
            ManagementOperationInfo[] operInfos = minfo.getAllManagementOperationInfos();
            Arrays.sort(operInfos);

            for(int i = 0; i < operInfos.length; i++) {
                ManagementOperationInfo operInfo = operInfos[i];

                sb.append("  <tr height=\"30\">\n" +
                        "  <form>\n" +
                        "    <input type=\"hidden\" name=\"action\" value=\"InvokeComponent\">\n" +
                        "    <input type=\"hidden\" name=\"compname\" value=\"")
                        .append(meta.getComponentName().toString())
                        .append("\">\n" +
                        "    <input type=\"hidden\" name=\"operHashCode\" value=\"")
                        .append(operInfo.getMethodHashCode())
                        .append("\">\n" +
                        "    <td>");

                sb.append("\n      <table width=\"100%\" height=\"100%\">");

                Class[] paramTypes = operInfo.getParameterTypes();
                if(paramTypes.length == 0) {
                    sb.append("\n        <tr><td  align=\"right\">")
                            .append(operInfo.getReturnType().getName())
                            .append(" <a href=\"#\"title=\"")
                            .append(operInfo.getDescription())
                            .append("\">")
                            .append(operInfo.getName())
                            .append("</a>\n")
                            .append("( )\n        </td>")
                            .append("\n       </tr>");
                }
                else {
                    for(int j = 0; j < paramTypes.length; j++) {
                        sb.append("\n        <tr><td align=\"right\">");
                        if(j == 0) {
                            sb.append(operInfo.getReturnType().getName())
                                    .append(" <a href=\"#\"title=\"")
                                    .append(operInfo.getDescription())
                                    .append("\">")
                                    .append(operInfo.getName())
                                    .append("</a>\n");
                            sb.append("        (");
                        }
                        else {
                            sb.append("&nbsp;");
                        }
                        sb.append("\n          <i>")
                                .append(paramTypes[j].getName())
                                .append("</i>\n");
                        if(j < paramTypes.length - 1) {
                            sb.append(",<br>");
                        }
                        if(j == paramTypes.length - 1) sb.append("        )");
                        sb.append("\n        </td></tr>");
                    }
                }
                sb.append("\n      </table>");
                sb.append("\n" +
                        "    </td>\n" +
                        "    <td>\n");
                if(operInfo.isGetter()) {
                    sb.append(operInfo.getMethod().invoke(meta.getComponentInstance(), new Class[]{}));
                }
                else {
                    for(int j = 0; j < paramTypes.length; j++) {
                        sb.append("      <input type=\"text\" name=\"")
                                .append(operInfo.getName()).append("_").append(j)
                                .append("\"><br>\n");
                    }
                }
                String operName = operInfo.getName();
                if(operName.length() > 15) operName = operName.substring(0, 13) + "..";
                sb.append("    </td>\n" +
                        "    <td>\n" +
                        "      <table>\n" +
                        "        <tr>\n" +
                        "          <td>\n" +
                        "          <input type=\"submit\" value=\"")
                        .append(operName)
                        .append(" \" title=\"invoke ")
                        .append(operInfo.getName())
                        .append("\">\n" +
                        "          </td>\n" +
                        "        </tr>\n" +
                        "        </table>\n" +
                        "    </td>\n" +
                        "    </form>\n" +
                        "  </tr>\n" +
                        "");
            }

        }
        sb.append("</table>\n");
        return sb.toString();
    }


    public static void main(String[] args) {

    }
}

