<!--

    Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!-- logViewer/logViewerRaw.jsf -->

<ui:event type="initPage">
    initSessionAttributes();
    setResourceBundle(key="i18nc" bundle="org.glassfish.common.admingui.Strings")
    setResourceBundle(key="i18n" bundle="org.glassfish.admingui.core.Strings");
</ui:event>

<sun:page id="page1">
<ui:event type="beforeCreate">
    getRequestValue(key="instanceName" value="#{pageSession.instanceName}");
    urlencode(value="#{pageSession.instanceName}" encoding="UTF-8" result="#{pageSession.encodedInstanceName}");
    gf.isInstanceName(instanceName="#{pageSession.instanceName}" exists="#{requestScope.exists}" );
    if (! #{requestScope.exists}){
        gf.redirect("#{request.contextPath}/common/index.jsf");
    }

</ui:event>
<sun:html id="html2">
<sun:head id="propertyhead" title="$resource{i18nc.logViewerRaw.PageTitle}" debug="false" parseOnLoad="false">
	<h:outputScript name="jsf.js" library="jakarta.faces" target="head" />  
    <sun:script url="/resource/common/js/adminjsf.js" />
</sun:head>
<sun:body onLoad="javascript: logViewerRaw('/download/log/?contentSourceId=LogViewer&start=0&instanceName=#{pageSession.encodedInstanceName}&restUrl=' + encodeURIComponent('#{sessionScope.REST_URL}'))" id="body3">
<sun:form id="propertyForm">
#include "/common/shared/alertMsg_1.inc"
    <!-- Page Title -->
    <sun:title id="propertyContentPage" title="$resource{i18nc.logViewerRaw.PageTitle}" helpText="$resource{i18nc.logViewerRaw.PageHelp}">
    <!facet pageButtonsTop>
	<sun:panelGroup id="topButtons">
	    <sun:button id="closeButton" text="$resource{i18n.button.Close}" onClick="javascript: window.close(); return false;" >
	    </sun:button>
	</sun:panelGroup>
    </facet>
    </sun:title>
<sun:propertySheet id="propertySheetLogResults">
    <sun:propertySheetSection id="propertSectionLogResults">
	<sun:property id="instanceProp" labelAlign="left" noWrap="true" overlapLabel="false" label="$resource{i18nc.logViewer.instanceLabel}">
	    <sun:dropDown id="instance" selected="#{instanceName}" labels="#{requestScope.servers}" submitForm="true">
		<ui:event type="beforeCreate">
		    /* Get the server list */
		    gf.restRequest(
			endpoint="#{sessionScope.REST_URL}/servers/server.json"
			method="GET"
			result="#{requestScope.servers}");
		    gf.getMapKeys(Map="#{requestScope.servers.data.extraProperties.childResources}" Keys="#{requestScope.servers}");
		</ui:event>
		<ui:event type="command">
		    gf.navigate(page="#{request.contextPath}/common/logViewer/logViewerRaw.jsf");
		</ui:event>
	    </sun:dropDown>
	</sun:property>
    </sun:propertySheetSection>

</sun:propertySheet>
<f:verbatim>
<pre id="log" style="padding: 10px; font-size: 143% /* it is 100% */"></pre>
<script type="text/javascript">
function logViewerRaw(url) {

    var timeout = 1000;
    
    var success = function(xhr, targetId, requestedUrl) {
        if (xhr.status == 200 && xhr.getResponseHeader('Content-Type') == "text/plain") {
            if (xhr.responseText ) {
                var records = document.createTextNode(xhr.responseText);
                var documentX = window.pageXOffset || document.body.scrollLeft /* IE */;
                var documentY = window.pageYOffset || document.body.scrollTop /* IE */;
                // http://stackoverflow.com/questions/5060389/how-do-you-know-the-scroll-bar-has-reached-bottom-of-a-page
                //var atBottom = $(window).scrollTop() == $(document).height() - $(window).height();
                var atBottom  = (documentY == document.documentElement.scrollHeight - document.documentElement.clientHeight);
                var $log = document.getElementById(targetId);
                $log.appendChild(records);
                if (atBottom) {
                  window.scrollTo(documentX, document.documentElement.scrollHeight - document.documentElement.clientHeight);
                }
            }
            // get only new records next time
            var nextRestUrl = xhr.getResponseHeader('X-Text-Append-Next');
            if (nextRestUrl != undefined) {
	            var matches = nextRestUrl.match(/start=\\d+/)
	            if (matches) {
	                url = url.replace(/start=\\d+/, matches[0]);
	            }
            }
        }
        setTimeout(poll, timeout);
    };

    var poll = function() {
        admingui.ajax.get(url, 'log', success);
    }
    
    poll();
}
</script>
</f:verbatim>
</sun:form>
</sun:body>
</sun:html>
</sun:page>
