package org.zstack.kvm;

import org.springframework.beans.factory.annotation.Autowired;
import org.zstack.core.config.GlobalConfig;
import org.zstack.core.config.GlobalConfigUpdateExtensionPoint;
import org.zstack.core.config.resourceconfig.ResourceConfigFacade;
import org.zstack.header.Component;
import org.zstack.header.allocator.HostReservedCapacityExtensionPoint;
import org.zstack.header.allocator.ReservedHostCapacity;
import org.zstack.utils.SizeUtils;

/**
 */
public class KvmHostReserveExtension implements HostReservedCapacityExtensionPoint, Component {
    private ReservedHostCapacity reserve = new ReservedHostCapacity();

    @Autowired
    ResourceConfigFacade rcf;

    @Override
    public String getHypervisorTypeForHostReserveCapacityExtension() {
        return KVMConstant.KVM_HYPERVISOR_TYPE;
    }

    @Override
    public ReservedHostCapacity getReservedHostCapacity(String hostUuid) {
        ReservedHostCapacity hc = new ReservedHostCapacity();
        hc.setReservedCpuCapacity(reserve.getReservedCpuCapacity());
        String reserveMem = rcf.getResourceConfigValue(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY, hostUuid, String.class);
        hc.setReservedMemoryCapacity(SizeUtils.sizeStringToBytes(reserveMem));
        return reserve;
    }

    @Override
    public boolean start() {
        long cpu = SizeUtils.sizeStringToBytes(KVMGlobalConfig.RESERVED_CPU_CAPACITY.value());
        long mem = SizeUtils.sizeStringToBytes(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY.value());
        reserve.setReservedCpuCapacity(cpu);
        reserve.setReservedMemoryCapacity(mem);

        KVMGlobalConfig.RESERVED_CPU_CAPACITY.installUpdateExtension(new GlobalConfigUpdateExtensionPoint() {
            @Override
            public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) {
                reserve.setReservedCpuCapacity(SizeUtils.sizeStringToBytes(newConfig.value()));
            }
        });
        KVMGlobalConfig.RESERVED_MEMORY_CAPACITY.installUpdateExtension(new GlobalConfigUpdateExtensionPoint() {
            @Override
            public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) {
                reserve.setReservedMemoryCapacity(SizeUtils.sizeStringToBytes(newConfig.value()));
            }
        });
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}

@@ -81,16 +81,58 @@
 owired;%0A
+import org.zstack.core.cloudbus.CloudBus;%0A
 import o
@@ -167,16 +167,16 @@
 Config;%0A
-
 import o
@@ -223,32 +223,93 @@
 ExtensionPoint;%0A
+import org.zstack.core.config.resourceconfig.ResourceConfig;%0A
 import org.zstac
@@ -391,24 +391,82 @@
 .Component;%0A
+import org.zstack.header.allocator.HostAllocatorConstant;%0A
 import org.z
@@ -581,16 +581,194 @@
 pacity;%0A
+import org.zstack.header.cluster.ClusterVO;%0Aimport org.zstack.header.host.HostVO;%0Aimport org.zstack.header.host.RecalculateHostCapacityMsg;%0Aimport org.zstack.header.zone.ZoneVO;%0A
 import o
@@ -1015,16 +1015,49 @@
 ade rcf;
+%0A    @Autowired%0A    CloudBus bus;
 %0A%0A    @O
@@ -1626,23 +1626,18 @@
  return 
-reserve
+hc
 ;%0A    %7D%0A
@@ -2667,35 +2667,1155 @@
     %7D);%0A
-        return true
+%0A        ResourceConfig reservedConfig = rcf.getResourceConfig(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY.getIdentity());%0A        reservedConfig.installLocalUpdateExtension((config, resourceUuid, resourceType, oldValue, newValue) -%3E%0A                recalculateHostCapacity(resourceUuid, resourceType));%0A        reservedConfig.installLocalDeleteExtension((config, resourceUuid, resourceType, originValue) -%3E%0A                recalculateHostCapacity(resourceUuid, resourceType));%0A%0A        return true;%0A    %7D%0A%0A    private void recalculateHostCapacity(String resourceUuid, String resourceType) %7B%0A        RecalculateHostCapacityMsg msg = new RecalculateHostCapacityMsg();%0A        bus.makeTargetServiceIdByResourceUuid(msg, HostAllocatorConstant.SERVICE_ID, resourceUuid);%0A        if (resourceType.equals(ZoneVO.class.getSimpleName())) %7B%0A            msg.setZoneUuid(resourceUuid);%0A        %7D else if (resourceType.equals(ClusterVO.class.getSimpleName())) %7B%0A            msg.setClusterUuid(resourceUuid);%0A        %7D else if (resourceType.equals(HostVO.class.getSimpleName())) %7B%0A            msg.setHostUuid(resourceUuid);%0A        %7D%0A        bus.send(msg)
 ;%0A    %7D%0A

fix reserved host mem update Resolves ZSTAC-19321