content: /*
   * Copyright (C) 2016-2023 ActionTech.
   * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
   */
  
  package com.actiontech.dble.singleton;
  
  import com.actiontech.dble.cluster.values.RawJson;
  import com.actiontech.dble.config.model.ClusterConfig;
  import com.actiontech.dble.config.util.ConfigException;
  import com.actiontech.dble.meta.ReloadLogHelper;
  import com.actiontech.dble.route.sequence.handler.*;
  import com.actiontech.dble.services.FrontendService;
  import com.google.common.collect.Sets;
  import org.slf4j.Logger;
  
  import javax.annotation.Nullable;
  import java.sql.SQLNonTransientException;
  import java.util.Set;
  
  /**
   * Created by szf on 2019/9/19.
   */
  public final class SequenceManager {
      private static final SequenceManager INSTANCE = new SequenceManager();
      private SequenceHandler handler;
  
      private SequenceManager() {
      }
  
      public static void init() {
          int seqHandlerType = ClusterConfig.getInstance().getSequenceHandlerType();
          INSTANCE.handler = newSequenceHandler(seqHandlerType);
      }
  
      private static SequenceHandler newSequenceHandler(int seqHandlerType) {
          switch (seqHandlerType) {
              case ClusterConfig.SEQUENCE_HANDLER_MYSQL:
                  return new IncrSequenceMySQLHandler();
              case ClusterConfig.SEQUENCE_HANDLER_LOCAL_TIME:
                  return new IncrSequenceTimeHandler();
              case ClusterConfig.SEQUENCE_HANDLER_ZK_DISTRIBUTED:
                  if (ClusterConfig.getInstance().isClusterEnable() && ClusterConfig.getInstance().useZkMode()) {
                      return new DistributedSequenceHandler();
                  } else {
                      throw new java.lang.IllegalArgumentException("Invalid sequence handler type " + seqHandlerType + " for no-zk cluster");
                  }
              case ClusterConfig.SEQUENCE_HANDLER_ZK_GLOBAL_INCREMENT:
                  if (ClusterConfig.getInstance().isClusterEnable() && ClusterConfig.getInstance().useZkMode()) {
                      return new IncrSequenceZKHandler();
                  } else {
                      throw new java.lang.IllegalArgumentException("Invalid sequence handler type " + seqHandlerType + " for no-zk cluster");
                  }
              default:
                  throw new java.lang.IllegalArgumentException("Invalid sequence handler type " + seqHandlerType);
          }
      }
  
      public static void load(RawJson sequenceJson, Set<String> currentShardingNodes) {
          if (INSTANCE.handler == null)
              return;
          INSTANCE.handler.load(sequenceJson, currentShardingNodes);
      }
  
      public static void reload(RawJson sequenceJson, Set<String> currentShardingNodes) {
          if (INSTANCE.handler == null)
              return;
          int seqHandlerType = ClusterConfig.getInstance().getSequenceHandlerType();
          switch (seqHandlerType) {
              case ClusterConfig.SEQUENCE_HANDLER_MYSQL:
              case ClusterConfig.SEQUENCE_HANDLER_ZK_GLOBAL_INCREMENT:
                  ReloadLogHelper.briefInfo("loadSequence ...");
                  INSTANCE.handler.load(sequenceJson, currentShardingNodes);
                  break;
              default:
                  break;
          }
      }
  
      public static void tryLoad(RawJson sequenceJson, Set<String> currentShardingNodes, Logger logger) {
          int seqHandlerType = ClusterConfig.getInstance().getSequenceHandlerType();
          switch (seqHandlerType) {
              case ClusterConfig.SEQUENCE_HANDLER_MYSQL:
              case ClusterConfig.SEQUENCE_HANDLER_ZK_GLOBAL_INCREMENT:
                  logger.info("[dry-run] loadSequence ...");
                  SequenceHandler tmpHandler = newSequenceHandler(seqHandlerType);
                  tmpHandler.tryLoad(sequenceJson, currentShardingNodes);
                  break;
              default:
                  break;
          }
      }
  
      public static long nextId(String prefixName, @Nullable FrontendService frontendService) throws SQLNonTransientException {
          if (INSTANCE.handler == null)
              throw new ConfigException("sequence is not init");
          return INSTANCE.handler.nextId(prefixName, frontendService);
      }
  
      public static SequenceHandler getHandler() {
          return INSTANCE.handler;
      }
  
      public static Set<String> getShardingNodes(RawJson sequenceJson) {
          if (ClusterConfig.getInstance().getSequenceHandlerType() == ClusterConfig.SEQUENCE_HANDLER_MYSQL && sequenceJson != null) {
              return IncrSequenceMySQLHandler.getShardingNodes(sequenceJson);
          }
          return Sets.newHashSet();
      }
  }
  