package org.openspaces.grid.esm;

import org.openspaces.admin.Admin;
import org.openspaces.admin.AdminFactory;
import org.openspaces.admin.esm.deployment.ElasticDataGridDeployment;
import org.openspaces.admin.gsa.GridServiceAgent;
import org.openspaces.admin.gsa.GridServiceContainerOptions;
import org.openspaces.admin.space.SpaceDeployment;

public class InternalESMImpl {
    private final Admin admin = new AdminFactory().addGroup("moran-gigaspaces-7.1.0-XAPPremium-m5").createAdmin();
    
    public InternalESMImpl() {
        
    }

    public void deploy(ElasticDataGridDeployment deployment) {
        SpaceDeployment spaceDeployment = new SpaceDeployment(deployment.getDataGridName());
        int initialNumberOfJvms = MemorySettings.valueOf(deployment.getMinMemory()).dividedBy(deployment.getJvmSize());
        int maxNumberOfJvms = MemorySettings.valueOf(deployment.getMaxMemory()).dividedBy(deployment.getJvmSize());
        
        if (deployment.isHighlyAvailable()) {
            //double the number of jvms for backup spaces
            initialNumberOfJvms = Math.min(initialNumberOfJvms*2, maxNumberOfJvms);
            spaceDeployment.partitioned(maxNumberOfJvms, 1);
        } else {
            spaceDeployment.partitioned(maxNumberOfJvms, 0);
        }
        
        /*
         * On which machine can I load a GSC? 
         *  - exclude any machine with dedicated-private
         *  - exclude any machine with shared-private belonging to another tenant
         */
        admin.getGridServiceAgents().waitForAtLeastOne();
        int numberOfStartedJvms = 0;
        while (numberOfStartedJvms < initialNumberOfJvms) {
            //choose least active agent
            GridServiceAgent agentWithMinGSCs = null;
            for (GridServiceAgent agent : admin.getGridServiceAgents()) {
                if (agentWithMinGSCs == null || agent.getMachine().getGridServiceContainers().getSize() < 
                        agentWithMinGSCs.getMachine().getGridServiceContainers().getSize() ) {
                    agentWithMinGSCs = agent;
                }
            }
            agentWithMinGSCs.startGridService(new GridServiceContainerOptions().vmInputArgument("-Dcom.gs.zones="+deployment.getDataGridName()));
            numberOfStartedJvms++;
        }
        //wait for all GSCs started on this zone
        final String zone = deployment.getDataGridName();
        while (admin.getZones() == null || admin.getZones().getByName(zone) == null) {
            System.out.println("zone not yet discovered");
        }
        admin.getZones().getByName(zone).getGridServiceContainers().waitFor(initialNumberOfJvms);
        admin.getGridServiceManagers().deploy(spaceDeployment);
    }
}

@@ -959,198 +959,207 @@
     
-%0D%0A        if (deployment.isHighlyAvailable()) %7B%0D%0A            //double the number of jvms for backup spaces%0D%0A            initialNumberOfJvms = Math.min(initialNumberOfJvms*2, maxNumberOfJvms)
+int maxNumberOfPartitions = maxNumberOfJvms;%0D%0A        %0D%0A        boolean highlyAvailable = true;%0D%0A        if (highlyAvailable) %7B%0D%0A            initialNumberOfJvms *=2;%0D%0A            maxNumberOfJvms *= 2
 ;%0D%0A 
@@ -1208,19 +1208,25 @@
 NumberOf
-Jvm
+Partition
 s, 1);%0D%0A
@@ -1298,16 +1298,309 @@
 erOf
+Partitions, 0);%0D%0A        %7D%0D%0A        %0D%0A        int maxInstancesPerJvm = maxNumberOfJvms/initialNumberOfJvms;%0D%0A        if (maxInstancesPerJvm %3E 10) %7B%0D%0A            //..limit to 10%0D%0A            initialNumberOfJvms = maxNumberOfJvms/10;%0D%0A            maxInstancesPerJvm = maxNumberOfJvms/initialNumberOf
 Jvms
-, 0)
 ;%0D%0A 
@@ -2893,17 +2893,56 @@
 scovered
-%22
+ - admin.getZones()=%22 + admin.getZones()
 );%0D%0A    

improve deployment algorithm. Put a limit on the number of instances per jvm.