<%@ page import="org.jivesoftware.util.CookieUtils"%>
<%@ page import="org.jivesoftware.util.ParamUtils"%>
<%@ page import="org.jivesoftware.util.StringUtils"%>
<%@ page import="org.jivesoftware.util.cache.Cache"%>
<%@ page import="java.text.DecimalFormat"%>
<%@ page import="java.text.NumberFormat" %>
<%@ page import="org.jivesoftware.util.JiveGlobals" %>
<%--
  -
  - Copyright (C) 2005-2008 Jive Software. All rights reserved.
  -
  - Licensed 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.
--%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager"  />
<% webManager.init(request, response, session, application, out ); %>

<html>
    <head>
        <title><fmt:message key="system.cache.title"/></title>
        <meta name="pageID" content="system-cache"/>
        <script language="JavaScript" type="text/javascript">
        var selected = false;
        var cbstate = '';
        function handleCBClick(el) {
            var theform = el.form;
            for (var i=0; i<theform.elements.length; i++) {
                var theel = theform.elements[i];
                if (theel.name == 'cacheID') {
                    theel.checked = !selected;
                    toggleHighlight(theel);
                }
            }
            el.checked = !selected;
            selected = !selected;
            updateControls(theform);
        }
        function setCBState(theform) {
            for (var i=0; i<theform.elements.length; i++) {
                var theel = theform.elements[i];
                if (theel.name == 'cacheID') {
                    cbstate += theel.checked;
                }
            }
        }
        function clearCBs(theform) {
            for (var i=0; i<theform.elements.length; i++) {
                var theel = theform.elements[i];
                if (theel.name == 'cacheID') {
                    theel.checked = false;
                }
            }
        }
        function updateControls(theform) {
            var currentState = '';
            for (var i=0; i<theform.elements.length; i++) {
                var theel = theform.elements[i];
                if (theel.name == 'cacheID') {
                    currentState += theel.checked;
                }
            }
            if (currentState != cbstate) {
                theform.clear.disabled = false;
            }
            else {
                theform.clear.disabled = true;
            }
        }
        function toggleHighlight(el) {
            var r = null;
            if (el.parentNode && el.parentNode.parentNode) {
                r = el.parentNode.parentNode;
            }
            else if (el.parentElement && el.parentElement.parentElement) {
                r = el.parentElement.parentElement;
            }
            if (r) {
                if (el.checked) {
                    r.className = "jive-row-sel";
                }
                else {
                    r.className = "jive-row";
                }
            }
        }
        </script>
    </head>
    <body>

<% // Get parameters
    boolean doClearCache = request.getParameter("clear") != null;
    int[] cacheIDs = ParamUtils.getIntParameters(request, "cacheID", -1);

    // Get the list of existing caches
    Cache[] caches = webManager.getCaches();

    Cookie csrfCookie = CookieUtils.getCookie(request, "csrf");
    String csrfParam = ParamUtils.getParameter(request, "csrf");

    if (doClearCache) {
        if (csrfCookie == null || csrfParam == null || !csrfCookie.getValue().equals(csrfParam)) {
            doClearCache = false;
        }
    }
    csrfParam = StringUtils.randomString(15);
    CookieUtils.setCookie(request, response, "csrf", csrfParam, -1);
    pageContext.setAttribute("csrf", csrfParam);
    // Clear one or multiple caches if requested.
    if (doClearCache) {
        for (int cacheID : cacheIDs) {
            final Cache cache = caches[cacheID];
            cache.clear();
            webManager.logEvent(String.format("Cleared cache '%s'", cache.getName()), null);
        }
    }

    NumberFormat numberFormatter = NumberFormat.getNumberInstance(JiveGlobals.getLocale());
    // decimal formatter for cache values
    DecimalFormat mbFormat = new DecimalFormat("#0.00");
    DecimalFormat percentFormat = new DecimalFormat("#0.0");
    percentFormat.setNegativePrefix("");
%>

<%  if (doClearCache) { %>

    <div class="jive-success">
    <table cellpadding="0" cellspacing="0" border="0">
    <tbody>
        <tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0" alt=""></td>
        <td class="jive-icon-label">
        <fmt:message key="system.cache.cleared" />
        </td></tr>
    </tbody>
    </table>
    </div><br>

<%  } %>

<p>
<fmt:message key="system.cache.info" />
</p>

<%  // cache variables
    double overallTotal = 0.0;
    double memUsed;
    double totalMem;
    double freeMem;
    double usedMem;
    String hitPercent;
    long hits;
    long misses;
%>

<form action="system-cache.jsp" method="post" name="cacheForm">
        <input type="hidden" name="csrf" value="${csrf}">

<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
    <tr>
        <th width="39%" nowrap><fmt:message key="system.cache.head.name" /></th>
        <th width="10%" nowrap><fmt:message key="system.cache.head.max" /></th>
        <th width="10%" nowrap><fmt:message key="system.cache.head.lifetime" /></th>
        <th width="10%" nowrap style="text-align: center;" colspan="2"><fmt:message key="system.cache.head.current" /></th>
        <th width="10%" nowrap><fmt:message key="system.cache.head.percent" /></th>
        <th width="20%" nowrap style="text-align: center;" colspan="2"><fmt:message key="system.cache.head.effectiveness" /></th>
        <th width="1%" class="c5"><input type="checkbox" name="" value="" onclick="handleCBClick(this);"></th>
    </tr>
</thead>
<tbody>

<%  // Loop through each cache, print out its info
    for (int i=0; i<caches.length; i++) {
        Cache cache = caches[i];
        if (cache.getMaxCacheSize() != -1 && cache.getMaxCacheSize() != Integer.MAX_VALUE) {
            overallTotal += (double)cache.getMaxCacheSize();
        }
        int entries = cache.size();
        memUsed = (double)cache.getCacheSize()/(1024*1024);
        totalMem = (double)cache.getMaxCacheSize()/(1024*1024);
        freeMem = 100 - 100*memUsed/totalMem;
        usedMem = 100*memUsed/totalMem;
        hits = cache.getCacheHits();
        misses = cache.getCacheMisses();
        boolean lowEffec = false;
        if (hits + misses == 0) {
            hitPercent = "N/A";
        }
        else {
            double hitValue = 100*(double)hits/(hits+misses);
            hitPercent = percentFormat.format(hitValue) + "%";
            lowEffec = (hits > 500 && hitValue < 85.0 && freeMem < 20.0);
        }
        // OF-1365: Don't allow caches that do not expire to be purged. Many of these caches store data that cannot be recovered again.
        final boolean canPurge = cache.getMaxLifetime() > -1;
%>
    <tr class="<%= (lowEffec ? "jive-error" : "") %>">
        <td class="c1">
            <table cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td class="icon"><img src="images/cache-16x16.gif" width="16" height="16" alt="" border="0"></td>
                <td><%= StringUtils.escapeHTMLTags(cache.getName()) %></td>
            </tr>
            </table>
        </td>
        <td class="c2">
            <% if (cache.getMaxCacheSize() != -1 && cache.getMaxCacheSize() != Integer.MAX_VALUE) { %>
                <%= mbFormat.format(totalMem) %> MB
            <% } else { %>
                <fmt:message key="global.unlimited" />
            <% } %>
        </td>
        <td class="c2">
            <% if (cache.getMaxLifetime() != -1) { %>
                <%= StringUtils.getFullElapsedTime(cache.getMaxLifetime()) %>
            <% } else { %>
                <fmt:message key="global.unlimited" />
            <% } %>
        </td>
        <td class="c3" style="text-align: right; padding-right:0;">
            <%=numberFormatter.format(entries)%>&nbsp;
        </td>
        <td class="c3" style="text-align: left; padding-left:0;">
            / <%= mbFormat.format(memUsed)%> MB
        </td>
        <td class="c3">
            <% if (cache.getMaxCacheSize() != -1 && cache.getMaxCacheSize() != Integer.MAX_VALUE) { %>
                <%= percentFormat.format(usedMem)%>%
            <% } else { %>
                N/A
            <% } %>
        </td>
        <td class="c4" style="text-align: right; padding-right:0;">
            <%=numberFormatter.format(hits)%>/<%=numberFormatter.format(hits + misses)%>&nbsp;
        </td>
        <td class="c4" style="text-align: left; padding-left:0;">
            (<%=hitPercent%>)
        </td>

        <td width="1%" class="c5">
            <% if ( canPurge ) {%>
            <input type="checkbox" name="cacheID" value="<%= i %>" onclick="updateControls(this.form);toggleHighlight(this);">
            <% } %>
        </td>
    </tr>

<%  } %>

<tr bgcolor="#eeeeee">
    <td align="right" class="c1">
        <fmt:message key="system.cache.total" />
    </td>
    <td class="c2">
        <%= mbFormat.format(overallTotal/(1024.0*1024.0)) %> MB
    </td>
    <td align="right" colspan="7">
        <input type="submit" name="clear" value="<fmt:message key="system.cache.clear-selected" />" disabled>
    </td>
</tr>
</tbody>
</table>
</div>

<p class="jive-description">
<fmt:message key="system.cache.desc.effectiveness" />
</p>

    <script language="JavaScript" type="text/javascript">
    clearCBs(document.cacheForm);
    setCBState(document.cacheForm);
    </script>

    </form>

    </body>
</html>
