<%@ page import="com.atlassian.core.ofbiz.CoreFactory"%>
<%@ page import="com.atlassian.core.ofbiz.CoreFactory"%>
<%@ page import="com.atlassian.jira.util.map.EasyMap"%>
<%@ page import="org.ofbiz.core.entity.*"%>
<%@ page import="com.opensymphony.util.TextUtils"%>
<%@ page import="java.io.IOException"%>
<%@ page import="com.atlassian.jira.ComponentManager"%>
<%@ page import="com.atlassian.jira.util.EasyList"%>
<%@ page import="java.util.Map"%>
<%@ page import="com.opensymphony.user.User"%>
<%@ page import="webwork.action.ActionContext"%>
<%@ page import="com.atlassian.seraph.auth.DefaultAuthenticator"%>
<%@ page import="com.atlassian.jira.ManagerFactory"%>
<%@ page import="com.atlassian.jira.security.Permissions"%>
<%@ taglib uri="webwork" prefix="webwork" %>
<%@ taglib uri="sitemesh-page" prefix="page" %>

<%!
    private static final String COMMENT_TABLE_ENTITY_NAME = "Action";
    private static final String MODE_PARAM_NAME = "mode";
    private static final String COMMENT_ID_PARAM_NAME = "comment_id";
%>

<html>
	<head>
		<title>Clean Comment Spam</title>
	</head>
	<body>

    <%
        // Check that the user has permissions
        User remoteUser = (User) request.getSession().getAttribute(DefaultAuthenticator.LOGGED_IN_KEY);
        // If the user is not logged in or does not have the global ADMIN permission then give back an error message.
        if (remoteUser == null || !ManagerFactory.getPermissionManager().hasPermission(Permissions.ADMINISTER, remoteUser))
        {
            out.println("<p><p class=\"warningBox\">You do not have permissions to ADMINISTER JIRA.</p></p>");
            return;
        }
    %>

    <%
        String mode = request.getParameter(MODE_PARAM_NAME);
        if ("confirm".equals(mode))
        {
            String[] commentIds = request.getParameterValues(COMMENT_ID_PARAM_NAME);
            if (commentIds != null && commentIds.length > 0)
            {
    %>
            <%-- Confirm Mode --%>
            <page:applyDecorator name="jirapanel">
                <page:param name="title">Delete Comments</page:param>
                <page:param name="description">
                    <p>
                        Please confirm that you would like to delete the comments shown in the table below.
                    </p>

                    <p class="warningBox">
                        The deleted comments <strong>will not be recorded</strong> into change history of their issue. Once you confirm this screen, there will be
                        no way to restore these comments.
                    </p>
                </page:param>
            </page:applyDecorator>

            <form action="cleancommentspam.jsp">
                <table width="100%" border="1" class="grid">
                    <tr>
                        <th>&nbsp;</th>
                        <th>Comment</th>
                        <th>Comment Author</th>
                        <th>Created Date</th>
                        <th>Comment ID</th>
                        <th>Issue</th>
                    </tr>

                    <%
                    for (int i = 0; i < commentIds.length; i++)
                    {
                        Long commentId = new Long(commentIds[i]);
                        printComment(out, getComment(commentId), request, false);
                    }
                    %>
                </table>
                <input type="hidden" name="<%= MODE_PARAM_NAME %>" value="delete" />
                <input type="submit" value="Delete" />
                <input type="button" value="Cancel" onClick="location.href='<%= request.getContextPath()%>/secure/admin/cleancommentspam.jsp'" />
            </form>
    <%
            }
            else
            {
    %>
                    <p class="warningBox">
                        No comments to delete were selected. Please select at least one comment to delete.
                    </p>
                    <p>
                        <a href="cleancommentspam.jsp">&lt;&lt; Return</a>
                    </p>
    <%
            }
        }
        else if ("delete".equals(mode))
        {
            // Delete Mode

            String[] commentIds = request.getParameterValues(COMMENT_ID_PARAM_NAME);
            if (commentIds != null && commentIds.length > 0)
            {
                for (int i = 0; i < commentIds.length; i++)
                {
                    Long commentId = new Long(commentIds[i]);
                    int numberDeleted = deleteComment(commentId);
                    if (numberDeleted > 0)
                    {
                        out.println("Deleted comment with id " + commentId + " <br />");
                    }
                    else
                    {
                        out.println("<span class=\"warning\">Could not delete comment with id " + commentId + "</span><br />");
                    }
                }

                out.println("<p><a href=\"cleancommentspam.jsp\">&lt;&lt;Return</a></p>");
            }
            else
            {
              %>
                <p class="warningBox">
                    No comments to delete were selected. Please select at least one comment to delete.
                </p>
                <p>
                    <a href="cleancommentspam.jsp">&lt;&lt; Return</a>
                </p>
              <%
            }
        }
        else
        {
    %>
            <%-- Default Mode --%>
            <%
               int numberOfComments = 100;
               String ncs = request.getParameter("numberComments");
               if (ncs != null)
               {
                   try
                   {
                       numberOfComments = Integer.parseInt(ncs);
                   }
                   catch (NumberFormatException e)
                   {
                       // Ignore and leave the variable to be 100
                   }
               }
            %>

            <page:applyDecorator name="jirapanel">
                <page:param name="title">Clean Comment Spam</page:param>
                <page:param name="columns">1</page:param>
                <page:param name="description">
                    This page shows most recently created comments matching the filter criteria. The most recently added comment is shown first.

                    <p>
                        Please refine the filter criteria and press "Filer", or  select the comments you would like to delete and press "Delete".
                    </p>
                    <p>
                        <span class="warning">Note</span>: The deleted comments will not be recorded into change history of their issue.
                    </p>

                    <form action="cleancommentspam.jsp">
                        <b>Max number comments:</b> <input type="text" name="numberComments" value="<%= numberOfComments %>" size="3" />
                        <b>Author:</b> <input type="text" name="commentAuthor" value="<%= TextUtils.noNull(request.getParameter("commentAuthor")) %>" />
                        <b>Min number of links:</b> <input type="text" name="commentLinksNumber" value="<%= TextUtils.noNull(request.getParameter("commentLinksNumber")) %>" />

                        <input type="hidden" name="<%= MODE_PARAM_NAME %>" value="filter" />
                        <input type="submit" value="Filter" />
                    </form>

                </page:param>
            </page:applyDecorator>

            <form action="cleancommentspam.jsp">
                    <table width="100%" class="grid">
                    <tr>
                        <th>&nbsp;</th>
                        <th>Comment</th>
                        <th>Comment Author</th>
                        <th>Created Date</th>
                        <th>Comment ID</th>
                        <th>Issue</th>
                    </tr>
                    <%
                        Map conditionMap = EasyMap.build("type", "comment");
                        String commentAuthor = request.getParameter("commentAuthor");
                        if (TextUtils.stringSet(commentAuthor))
                        {
                            conditionMap.put("author", commentAuthor);
                        }
                        EntityFieldMap entityFieldMap = new EntityFieldMap(conditionMap, EntityOperator.AND);


                        int commentLinksNumber = 0;
                        try
                        {
                            commentLinksNumber = Integer.parseInt(request.getParameter("commentLinksNumber"));
                        }
                        catch (NumberFormatException e)
                        {
                            // Ignore
                        }

                        EntityCondition condition;
                        if (commentLinksNumber > 0)
                        {
                            StringBuffer queryString = new StringBuffer("%");
                            for (int i = 0; i < commentLinksNumber; i++)
                            {
                                queryString.append("http://%");
                            }

                            EntityExpr linksCondition = new EntityExpr("body", EntityOperator.LIKE, queryString.toString());
                            condition = new EntityExpr(entityFieldMap, EntityOperator.AND, linksCondition);
                        }
                        else
                        {
                            condition = entityFieldMap;
                        }

                        boolean commentsFound = false;
                        EntityListIterator listIterator = null;
                        try
                        {
                            listIterator = CoreFactory.getGenericDelegator().findListIteratorByCondition(COMMENT_TABLE_ENTITY_NAME, condition, null, EasyList.build("created DESC"));
                            GenericValue commentGV = (GenericValue) listIterator.next();
                            int i = 0;
                            while (commentGV != null)
                            {
                                commentsFound = true;
                                if (++i > numberOfComments)
                                {
                                    break;
                                }

                                printComment(out, commentGV, request, true);

                                commentGV = (GenericValue) listIterator.next();
                            }
                        }
                        finally
                        {
                            if (listIterator != null)
                            {
                                listIterator.close();
                            }
                        }

                        if (!commentsFound)
                        {
                             out.println("<tr><td colspan=\"6\">No comments were found.</td></tr>");
                        }
                    %>
                    </table>
                    <input type="hidden" name="<%= MODE_PARAM_NAME %>" value="confirm" />
                    <input type="submit" value="Delete" />
            </form>
    <%
        }
    %>
    </body>
</html>

<%!


    private void printComment(JspWriter out, GenericValue commentGV, HttpServletRequest request, boolean input) throws IOException
    {
        out.println("<tr>");
        out.println("<td>");
        if (input)
        {
            out.print("<input type=\"checkbox\" name=\"" + COMMENT_ID_PARAM_NAME + "\" value=\"" + commentGV.getLong("id") + "\" />");
        }
        else
        {
            out.print("<input type=\"hidden\" name=\"" + COMMENT_ID_PARAM_NAME + "\" value=\"" + commentGV.getLong("id") + "\" />");
        }
        out.println("</td>");
        out.println("<td width=\"100%\">");

        out.println(TextUtils.plainTextToHtml(commentGV.getString("body")));

        out.println("</td>");
        out.println("<td>");
        out.println(TextUtils.htmlEncode(commentGV.getString("author")));
        out.println("</td>");
        out.println("<td>");
        out.println(TextUtils.htmlEncode(commentGV.getString("created")));
        out.println("</td>");
        out.println("<td>");
        out.println(commentGV.getLong("id"));
        out.println("</td>");
        out.println("<td>");

        String issueKey = getIssueKey(commentGV);
        if (issueKey != null)
        {
            out.print("<a href=\"" + request.getContextPath() + "/browse/" + issueKey + "\">");
            out.print(issueKey);
            out.println("</a>");
        }
        else
        {
            out.println("&nbsp;");
        }

        out.println("</td>");
        out.println("</tr>");
    }

    private GenericValue getComment(Long id) throws GenericEntityException
    {
        return CoreFactory.getGenericDelegator().findByPrimaryKey(COMMENT_TABLE_ENTITY_NAME, EasyMap.build("id", id));
    }

    private int deleteComment(Long id) throws GenericEntityException
    {
        return CoreFactory.getGenericDelegator().removeByAnd(COMMENT_TABLE_ENTITY_NAME, EasyMap.build("id", id, "type", "comment"));
    }

    private String getIssueKey(GenericValue commentGV)
    {
        GenericValue issueGV = null;
        Long issueId = commentGV.getLong("issue");
        try
        {
            issueGV = ComponentManager.getInstance().getIssueManager().getIssue(issueId);
		// This will be a GenericEntityException, but it isn't thrown in
		// recent versions of JIRA
        } catch (Exception e)
        {
            System.out.println("Error getting issue with id "+issueId+": "+e);
            e.printStackTrace();
        }
        if (issueGV != null)
        {
            return issueGV.getString("key");
        }

        return null;
    }
%>
