content: /*
   * Copyright 1999-$toady.year Alibaba Group Holding Ltd.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package com.alibaba.nacos.config.server.utils;
  
  import com.alibaba.nacos.common.utils.StringUtils;
  import com.alibaba.nacos.config.server.constant.Constants;
  import com.alibaba.nacos.config.server.model.ConfigAllInfo;
  import com.fasterxml.jackson.databind.JsonNode;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.node.ObjectNode;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * Extra info util.
   *
   * @author Nacos
   */
  public class ConfigExtInfoUtil {
      
      private static final Logger LOGGER = LoggerFactory.getLogger(ConfigExtInfoUtil.class);
      
      private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
      
      private static final Map<String, String> EXTRA_INFO_KEYS_MAPPING = new HashMap<>();
      
      static {
          EXTRA_INFO_KEYS_MAPPING.put("type", "type");
          EXTRA_INFO_KEYS_MAPPING.put("config_tags", "config_tags");
          EXTRA_INFO_KEYS_MAPPING.put("src_user", "src_user");
          EXTRA_INFO_KEYS_MAPPING.put("desc", "c_desc");
          EXTRA_INFO_KEYS_MAPPING.put("use", "c_use");
          EXTRA_INFO_KEYS_MAPPING.put("effect", "effect");
          EXTRA_INFO_KEYS_MAPPING.put("schema", "c_schema");
      }
      
      private ConfigExtInfoUtil() {
      }
      
      /**
       * Extract the extInfo from advance config info.
       */
      public static String getExtraInfoFromAdvanceInfoMap(Map<String, Object> advanceConfigInfoMap, String srcUser) {
          try {
              if (advanceConfigInfoMap == null || advanceConfigInfoMap.isEmpty()) {
                  return null;
              }
              
              ObjectNode node = OBJECT_MAPPER.createObjectNode();
              
              if (StringUtils.isNotBlank(srcUser)) {
                  node.put("src_user", srcUser);
              }
              
              for (Map.Entry<String, String> entry : EXTRA_INFO_KEYS_MAPPING.entrySet()) {
                  String key = entry.getKey();
                  String mappedKey = entry.getValue();
                  Object advanceConfigInfoValue = advanceConfigInfoMap.get(key);
                  if (advanceConfigInfoValue instanceof String && StringUtils.isNotBlank(
                          (String) advanceConfigInfoValue)) {
                      node.put(mappedKey, ((String) advanceConfigInfoValue).trim());
                  }
              }
              
              return OBJECT_MAPPER.writeValueAsString(node);
          } catch (Exception ex) {
              LOGGER.error("Failed to get extra info from advance info map", ex);
              return null;
          }
      }
      
      /**
       * Extract the extInfo from all config info.
       */
      public static String getExtInfoFromAllInfo(ConfigAllInfo configAllInfo) {
          ObjectNode node = OBJECT_MAPPER.createObjectNode();
          
          if (StringUtils.isNotBlank(configAllInfo.getType())) {
              node.put("type", configAllInfo.getType());
          }
          if (StringUtils.isNotBlank(configAllInfo.getConfigTags())) {
              node.put("config_tags", configAllInfo.getConfigTags());
          }
          if (StringUtils.isNotBlank(configAllInfo.getEffect())) {
              node.put("effect", configAllInfo.getEffect());
          }
          if (StringUtils.isNotBlank(configAllInfo.getCreateUser())) {
              node.put("src_user", configAllInfo.getCreateUser());
          }
          if (StringUtils.isNotBlank(configAllInfo.getDesc())) {
              node.put("c_desc", configAllInfo.getDesc());
          }
          if (StringUtils.isNotBlank(configAllInfo.getUse())) {
              node.put("c_use", configAllInfo.getUse());
          }
          if (StringUtils.isNotBlank(configAllInfo.getSchema())) {
              node.put("c_schema", configAllInfo.getSchema());
          }
          
          try {
              return OBJECT_MAPPER.writeValueAsString(node);
          } catch (Exception ex) {
              LOGGER.error("Failed to get extra info from all config info", ex);
              return null;
          }
      }
      
      /**
       * Extract the extInfo from gray config info.
       */
      public static String getExtInfoFromGrayInfo(String grayName, String grayRuleTmp, String oldSrcUser) {
          ObjectNode node = OBJECT_MAPPER.createObjectNode();
          ObjectNode grayRuleNode = OBJECT_MAPPER.createObjectNode();
          
          if (StringUtils.isNotBlank(grayName)) {
              node.put("gray_name", grayName);
          }
          
          if (StringUtils.isNotBlank(oldSrcUser)) {
              node.put("src_user", oldSrcUser);
          }
          
          if (StringUtils.isNotBlank(grayRuleTmp)) {
              try {
                  JsonNode parsedGrayRuleNode = OBJECT_MAPPER.readTree(grayRuleTmp);
                  if (parsedGrayRuleNode.has(Constants.GRAY_RULE_TYPE)) {
                      grayRuleNode.put(Constants.GRAY_RULE_TYPE,
                              parsedGrayRuleNode.get(Constants.GRAY_RULE_TYPE).asText());
                  }
                  if (parsedGrayRuleNode.has(Constants.GRAY_RULE_EXPR)) {
                      grayRuleNode.put(Constants.GRAY_RULE_EXPR,
                              parsedGrayRuleNode.get(Constants.GRAY_RULE_EXPR).asText());
                  }
                  if (parsedGrayRuleNode.has(Constants.GRAY_RULE_VERSION)) {
                      grayRuleNode.put(Constants.GRAY_RULE_VERSION,
                              parsedGrayRuleNode.get(Constants.GRAY_RULE_VERSION).asText());
                  }
                  if (parsedGrayRuleNode.has(Constants.GRAY_RULE_PRIORITY)) {
                      grayRuleNode.put(Constants.GRAY_RULE_PRIORITY,
                              parsedGrayRuleNode.get(Constants.GRAY_RULE_PRIORITY).asText());
                  }
                  node.put("gray_rule", grayRuleNode.toString());
              } catch (Exception ex) {
                  LOGGER.error("Failed to parse gray rule as json", ex);
                  return null;
              }
          }
          
          try {
              return OBJECT_MAPPER.writeValueAsString(node);
          } catch (Exception ex) {
              LOGGER.error("Failed to serialize extra info from gray info", ex);
              return null;
          }
      }
      
  }