#########################################################################
#
#   Copyright 2020-2021 VMware, Inc.  All rights reserved. VMware Confidential
#
#########################################################################
from os.path import join
from logging import getLogger
from cis.utils import (read_properties, replace_properties_in_file,
                       write_props_to_file)
from .patchUtil import TO_PREPARE_SUFFIX, updateVersion

VERSION = 2
EAM_CFG_DIR = "/etc/vmware-eam/"
LOG4J_PROPS = "log4j.properties"
EAM_VERSION = "version"
_EAM_LOG4J_PROPS_FILE_OLD = join(EAM_CFG_DIR, LOG4J_PROPS)
_EAM_LOG4J_PROPS_FILE_NEW = _EAM_LOG4J_PROPS_FILE_OLD +\
                         TO_PREPARE_SUFFIX
EAM_VERSION_OLD = join(EAM_CFG_DIR, EAM_VERSION)
EAM_VERSION_NEW = join(EAM_CFG_DIR, EAM_VERSION + TO_PREPARE_SUFFIX)

_EAM_LOG4J_PROPS_NEW = {
   "status": "warn",
   "monitorInterval": "60",
   "appender.rolling.type": "RollingFile",
   "appender.rolling.name": "fileLogger",
   "appender.rolling.fileName": "${vim.logdir}/eam.log",
   "appender.rolling.filePattern": "${vim.logdir}/eam-%i.log.gz",
   "appender.rolling.layout.type": "PatternLayout",
   "appender.rolling.layout.pattern": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} | %5p | %t | %F | %L | %m%n",
   "appender.rolling.policies.type": "Policies",
   "appender.rolling.policies.size.type": "SizeBasedTriggeringPolicy",
   "appender.rolling.policies.size.size": "100MB",
   "appender.rolling.strategy.type": "DefaultRolloverStrategy",
   "appender.rolling.strategy.max": "10",
   "logger.springframework.name": "org.springframework",
   "logger.springframework.level": "warn",
   "logger.eam.name": "com.vmware.eam",
   "logger.eam.level": "${eam.rootLogLevel}",
   "rootLogger.level": "warn",
   "rootLogger.appenderRef.rolling.ref": "fileLogger"
}

_OLD_TO_NEW_PROPS = {
   "log4j.logger.com.vmware.eam": "logger.eam.level",
   "log4j.appender.LOGFILE.RollingPolicy.ActiveFileName": "appender.rolling.fileName",
   "log4j.appender.LOGFILE.RollingPolicy.FileNamePattern": "appender.rolling.filePattern"}

_log = getLogger(__name__)

def run(ctx, isExpand):
   """
   Updates logging configuration to match log4j 2.x requirements.

   :param: ctx : B2B context
   :type: ctx : PatchContext, B2B specific structure, please refer to B2B
               documentation.
   :param: isExpand: boolean flag, True if this patch is invoked from expand
                    phase, False otherwise.
   :type: bool
   """
   _log.info("Updating log4j configuration.")

   file = _EAM_LOG4J_PROPS_FILE_NEW if isExpand else _EAM_LOG4J_PROPS_FILE_OLD
   versionFile = EAM_VERSION_NEW if isExpand else EAM_VERSION_OLD

   try:
      oldProps = read_properties(_EAM_LOG4J_PROPS_FILE_OLD, _OLD_TO_NEW_PROPS.keys());
      configToUpdate = {}

      for oldProp, newProp in _OLD_TO_NEW_PROPS.items():
         configToUpdate[newProp] = oldProps[oldProp]

      write_props_to_file(file, _EAM_LOG4J_PROPS_NEW.items())
      replace_properties_in_file(file, configToUpdate)

      updateVersion(VERSION, versionFile)
      _log.info("The log4 configuration was successfully updated")
   except Exception as e:
      _log.error("EAM version two patch failed.", e)
      raise e

def updateReplicationConfig(replicationConfig):
   """
   Updates given replication config with patch specific config
   file replication configuration.

   Each item in the dictionary have following semantic:
      Key -> path of a file from source machine
      Value -> path of a file from target machine
   The file from source machine is replicated on the location pointed
   in the value over the target machine. If the Value is None, the file
   is not replicated.

   :param: replicationConfig: dictionary where to place patch specific
           config replication.
   :type: dict(str, str)
   """
   replicationConfig[EAM_VERSION_OLD] = None
   replicationConfig[EAM_VERSION_NEW] = EAM_VERSION_OLD
   replicationConfig[_EAM_LOG4J_PROPS_FILE_OLD] = None
   replicationConfig[_EAM_LOG4J_PROPS_FILE_NEW] = _EAM_LOG4J_PROPS_FILE_OLD
