<!--

    Copyright (c) 2010, 2018 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

-->

<!-- applications/manageTargets.jsf -->


<!initPage
    setResourceBundle(key="i18n" bundle="org.glassfish.admingui.core.Strings")
    setResourceBundle(key="help_common" bundle="org.glassfish.common.admingui.Helplinks")
/>
<!composition template="/templates/default.layout" guiTitle="$resource{i18n.manageResourceTargets.PageTitle}" >
<!define name="content">
    <event>
        <!beforeCreate
            getRequestValue(key="resName" value="#{pageSession.resName}");
            getRequestValue(key="generalPage" value="#{pageSession.generalPage}");
            setPageSessionAttribute(key="resourceName" value="#{pageSession.resName}");
            urlencode(value="#{pageSession.resName}" encoding="UTF-8" result="#{pageSession.encodedResName}");
#include "/common/shared/targetsList.inc"
            setPageSessionAttribute(key="resTargets" value={});
            foreach(var="targetName" list="#{pageSession.targetList}") {
                 gf.checkIfEndPointExist(endpoint="#{sessionScope.REST_URL}/clusters/cluster/#{requestScope.targetName}/resource-ref/#{pageSession.encodedResName}" exists="isCluster");
                 if ("!#{requestScope.isCluster}") {
                     gf.checkIfEndPointExist(endpoint="#{sessionScope.REST_URL}/servers/server/#{requestScope.targetName}/resource-ref/#{pageSession.encodedResName}" exists="isServer");
                     if("#{requestScope.isServer}") {
                         listAdd(list="#{pageSession.resTargets}" value="#{requestScope.targetName}");
                     }
                 }
                 if ("#{requestScope.isCluster}") {
                     listAdd(list="#{pageSession.resTargets}" value="#{requestScope.targetName}");
                 }
             }
             convertListToArray(list="#{pageSession.resTargets}" array="#{pageSession.selectedTargets}");
        />
    </event>
<sun:form id="form">
    <!afterCreate
        getClientId(component="$this{component}" clientId=>$attribute{formId})
    />

#include "/common/shared/alertMsg_1.inc"
<sun:title id="propertyContentPage" title="$resource{i18n.manageResourceTargets.PageTitle}" helpText="$resource{i18n.manageResourceTargets.PageTitleHelp}">
    <!facet pageButtonsTop>
        <sun:panelGroup id="topButtons">
            <sun:button id="saveButton"  text="$resource{i18n.button.Save}" 
                    onClick="submitAndDisable(this, '$resource{i18n.button.Processing}'); return false;" >
                <!command
                    setAttribute(key="clusterEndpoint" value="#{sessionScope.REST_URL}/clusters/cluster");
                    setAttribute(key="serverEndpoint" value="#{sessionScope.REST_URL}/servers/server");
                    //Convert the seleted Targets Array to String
                    convertArrayToCommaString(array="#{pageSession.selectedTargets}" commaString="#{requestScope.selTargetsString}");
                    convertStringtoList(str="#{requestScope.selTargetsString}" result="#{requestScope.selTargetsList}");
                    
                    //For each selected target, verify if it is an already associated target.
                    //If it is already associated, no need to add or remove.
                    //If it is a new target, create an element under the target.
                    foreach(var="newTarget" list="#{requestScope.selTargetsList}") {
                        gf.containedIn(list="#{pageSession.resTargets}" testStr="#{newTarget}" contain="#{requestScope.isAssociatedTarget}");
                        if (#{requestScope.isAssociatedTarget}) {
                            //no need to add or remove.
                            removeListElement(list="#{pageSession.resTargets}" name="#{newTarget}" finalList="#{pageSession.resTargets}");
                        }
                        if (!#{requestScope.isAssociatedTarget}) {
                            gf.containedIn(list="#{pageSession.clusterList}" testStr="#{newTarget}" contain="#{requestScope.isCluster}");
                            if (#{requestScope.isCluster}) {
                                setAttribute(key="endpoint" value="#{clusterEndpoint}/#{newTarget}/resource-ref");
                            }
                            if (!#{requestScope.isCluster}) {
                                setAttribute(key="endpoint" value="#{serverEndpoint}/#{newTarget}/resource-ref");
                            }
                            createMap(result="#{requestScope.resAttrsMap}");
                            mapPut(map="#{requestScope.resAttrsMap}" key="id" value="#{pageSession.resName}");
                            mapPut(map="#{requestScope.resAttrsMap}" key="target" value="#{newTarget}");
                            gf.restRequest(endpoint="#{endpoint}" attrs="#{requestScope.resAttrsMap}", method="post");
                        }
                    }
                    foreach(var="oTarget" list="#{pageSession.resTargets}") {
                        gf.containedIn(list="#{pageSession.clusterList}" testStr="#{oTarget}" contain="#{requestScope.isCluster}");
                        if (#{requestScope.isCluster}) {
                            setAttribute(key="endpoint" value="#{clusterEndpoint}/#{oTarget}/resource-ref/#{pageSession.encodedResName}");
                        }
                        if (!#{requestScope.isCluster}) {
                            setAttribute(key="endpoint" value="#{serverEndpoint}/#{oTarget}/resource-ref/#{pageSession.encodedResName}");
                        }
                        createMap(result="#{requestScope.resRefAttrsMap}");
                        mapPut(map="#{requestScope.resRefAttrsMap}" key="target" value="#{oTarget}");
                        gf.restRequest(endpoint="#{endpoint}" attrs="#{requestScope.resRefAttrsMap}", method="DELETE");
                    }
                    prepareSuccessfulMsg();
                    gf.redirect(page="#{request.contextPath}/common/resourceNode/resourceEditTargets.jsf?name=#{pageSession.encodedResName}&generalPage=#{pageSession.generalPage}&alertType=${alertType}&alertSummary=${alertSummary}&alertDetail=${alertDetail}");
                />
            </sun:button>
            <sun:button id="cancelButton" immediate="#{true}" primary="#{false}" rendered="#{pageSession.showCancelButton}" text="$resource{i18n.button.Cancel}" >
                <!command
                    gf.redirect(page="#{request.contextPath}/common/resourceNode/resourceEditTargets.jsf?name=#{pageSession.encodedResName}&generalPage=#{pageSession.generalPage}");
                />
            </sun:button>
        </sun:panelGroup>
    </facet>
</sun:title>
#include "/common/resourceNode/resourceNameSection.inc"
<event>
    <!afterCreate
        getUIComponent(clientId="#{formId}"  component=>$attribute{component})
        setPageSessionAttribute(key="setDefaultTarget" value="false");
        includeIntegrations(type="org.glassfish.admingui:uploadPropertySheetTargetSection" );
    />
</event>

<sun:hidden id="helpKey" value="$resource{help_common.manageResourceTarget}" />
</sun:form>

#include "/common/shared/changeButtonsJS.inc"
</define>
</composition>
