#!/usr/bin/env python
#
# Copyright 2020 VMware, Inc.  All rights reserved. -- VMware Confidential
#
"""
This module encapsulates the vsphere-ui memory manipulations. Currently vsphere-ui requires
around 3 GB of heap in L and XL environments, a function not supported to be configured in
cloudvm_ram_size, so a call with --setCustom parameter is required.
"""

import os
import logging
import subprocess

H5_CLIENT_SERVICE_NAME = 'vsphere-ui'
CLOUDVM_RAM_SIZE = os.environ['VMWARE_CLOUDVM_RAM_SIZE']
CLOUDVM_RAM_SIZE_SET_CUSTOM_OPTION = '--setCustom'
THRESHOLD_SIZE_FOR_LARGE_DEPLOYMENT = '1500'
MEGABYTES_FOR_LARGE_DEPLOYMENTS = '3000'

logger = logging.getLogger(__name__)

def try_increasing_max_heap():
    current_max_heap = __get_current_heap()
    if (int(THRESHOLD_SIZE_FOR_LARGE_DEPLOYMENT)
            < int(current_max_heap)
            < int(MEGABYTES_FOR_LARGE_DEPLOYMENTS)):
        logger.info('Detected Large Or XLarge deployment. Increasing max heap size.')
        __do_increase_max_heap()
    else:
        logger.info('Detected smaller than Large deployment or heap already increased.' + \
                    ' Will not increase max heap.')

def __get_current_heap():
    cmd = [CLOUDVM_RAM_SIZE,
           H5_CLIENT_SERVICE_NAME]
    p = subprocess.Popen(cmd,
                         stdout = subprocess.PIPE,
                         stderr = subprocess.PIPE)
    (out, err) = p.communicate()
    if p.returncode != 0:
        logger.error('Failed to get current the max heap size for vsphere-ui: ' + \
                     err.decode('utf-8') + \
                     '\nWill not increase the memory for vsphere-ui service')
        return 0
    current_max_heap = int(out)
    return current_max_heap

def __do_increase_max_heap():
    # Invokes the cloudvm-ram-size script to update the maximum heap size for
    # vsphere-ui service for large and extra-large deployment sizes.
    cmd = [CLOUDVM_RAM_SIZE,
           CLOUDVM_RAM_SIZE_SET_CUSTOM_OPTION,
           MEGABYTES_FOR_LARGE_DEPLOYMENTS,
           H5_CLIENT_SERVICE_NAME]
    logger.info('Invoking: {0}'.format(' '.join(cmd)))
    p = subprocess.Popen(cmd,
                         stdout = subprocess.PIPE,
                         stderr = subprocess.PIPE)
    (out, err) = p.communicate()
    if p.returncode != 0:
        logger.error('Failed to increase the max heap size for vsphere-ui '
                     'process: cloudvm-ram-size failed with : ' + \
                     err.decode('utf-8'))


