/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal.cli.commands;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;

import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.DeclarableType;
import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.configuration.RegionAttributesType.EvictionAttributes;
import org.apache.geode.cache.configuration.RegionAttributesType.ExpirationAttributesType;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.distributed.ConfigurationPersistenceService;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.management.cli.CliMetaData;
import org.apache.geode.management.cli.ConverterHint;
import org.apache.geode.management.cli.SingleGfshCommand;
import org.apache.geode.management.configuration.ClassName;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.functions.RegionAlterFunction;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;

public class AlterRegionCommand extends SingleGfshCommand {
  @CliCommand(value = CliStrings.ALTER_REGION, help = CliStrings.ALTER_REGION__HELP)
  @CliMetaData(relatedTopic = CliStrings.TOPIC_GEODE_REGION)
  public ResultModel alterRegion(
      @CliOption(key = CliStrings.ALTER_REGION__REGION, mandatory = true,
          optionContext = ConverterHint.REGION_PATH,
          help = CliStrings.ALTER_REGION__REGION__HELP) String regionPath,
      @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
          optionContext = ConverterHint.MEMBERGROUP,
          help = CliStrings.ALTER_REGION__GROUP__HELP) String[] groups,
      @CliOption(key = CliStrings.ALTER_REGION__ENTRYEXPIRATIONIDLETIME,
          help = CliStrings.ALTER_REGION__ENTRYEXPIRATIONIDLETIME__HELP) Integer entryExpirationIdleTime,
      @CliOption(key = CliStrings.ALTER_REGION__ENTRYEXPIRATIONIDLETIMEACTION,
          specifiedDefaultValue = "INVALIDATE",
          help = CliStrings.ALTER_REGION__ENTRYEXPIRATIONIDLETIMEACTION__HELP) ExpirationAction entryExpirationIdleTimeAction,
      @CliOption(key = CliStrings.ALTER_REGION__ENTRYEXPIRATIONTIMETOLIVE,
          help = CliStrings.ALTER_REGION__ENTRYEXPIRATIONTIMETOLIVE__HELP) Integer entryExpirationTTL,
      @CliOption(key = CliStrings.ALTER_REGION__ENTRYEXPIRATIONTTLACTION,
          specifiedDefaultValue = "INVALIDATE",
          help = CliStrings.ALTER_REGION__ENTRYEXPIRATIONTTLACTION__HELP) ExpirationAction entryExpirationTTLAction,
      @CliOption(key = CliStrings.ENTRY_IDLE_TIME_CUSTOM_EXPIRY, specifiedDefaultValue = "",
          help = CliStrings.ENTRY_IDLE_TIME_CUSTOM_EXPIRY_HELP) ClassName entryIdleTimeCustomExpiry,
      @CliOption(key = CliStrings.ENTRY_TTL_CUSTOM_EXPIRY, specifiedDefaultValue = "",
          help = CliStrings.ENTRY_TTL_CUSTOM_EXPIRY_HELP) ClassName entryTTLCustomExpiry,
      @CliOption(key = CliStrings.ALTER_REGION__REGIONEXPIRATIONIDLETIME,
          help = CliStrings.ALTER_REGION__REGIONEXPIRATIONIDLETIME__HELP) Integer regionExpirationIdleTime,
      @CliOption(key = CliStrings.ALTER_REGION__REGIONEXPIRATIONIDLETIMEACTION,
          specifiedDefaultValue = "INVALIDATE",
          help = CliStrings.ALTER_REGION__REGIONEXPIRATIONIDLETIMEACTION__HELP) ExpirationAction regionExpirationIdleTimeAction,
      @CliOption(key = CliStrings.ALTER_REGION__REGIONEXPIRATIONTTL,
          help = CliStrings.ALTER_REGION__REGIONEXPIRATIONTTL__HELP) Integer regionExpirationTTL,
      @CliOption(key = CliStrings.ALTER_REGION__REGIONEXPIRATIONTTLACTION,
          specifiedDefaultValue = "INVALIDATE",
          help = CliStrings.ALTER_REGION__REGIONEXPIRATIONTTLACTION__HELP) ExpirationAction regionExpirationTTLAction,
      @CliOption(key = CliStrings.ALTER_REGION__CACHELISTENER, specifiedDefaultValue = "",
          // split the input only with comma outside of json string
          optionContext = "splittingRegex=,(?![^{]*\\})",
          help = CliStrings.ALTER_REGION__CACHELISTENER__HELP) ClassName[] cacheListeners,
      @CliOption(key = CliStrings.ALTER_REGION__CACHELOADER, specifiedDefaultValue = "",
          help = CliStrings.ALTER_REGION__CACHELOADER__HELP) ClassName cacheLoader,
      @CliOption(key = CliStrings.ALTER_REGION__CACHEWRITER, specifiedDefaultValue = "",
          help = CliStrings.ALTER_REGION__CACHEWRITER__HELP) ClassName cacheWriter,
      @CliOption(key = CliStrings.ALTER_REGION__ASYNCEVENTQUEUEID, specifiedDefaultValue = "",
          help = CliStrings.ALTER_REGION__ASYNCEVENTQUEUEID__HELP) String[] asyncEventQueueIds,
      @CliOption(key = CliStrings.ALTER_REGION__GATEWAYSENDERID, specifiedDefaultValue = "",
          help = CliStrings.ALTER_REGION__GATEWAYSENDERID__HELP) String[] gatewaySenderIds,
      @CliOption(key = CliStrings.ALTER_REGION__CLONINGENABLED, specifiedDefaultValue = "true",
          help = CliStrings.ALTER_REGION__CLONINGENABLED__HELP) Boolean cloningEnabled,
      @CliOption(key = CliStrings.ALTER_REGION__EVICTIONMAX, specifiedDefaultValue = "0",
          help = CliStrings.ALTER_REGION__EVICTIONMAX__HELP) Integer evictionMax) {
    authorize(Resource.DATA, Operation.MANAGE, regionPath);

    Set<DistributedMember> targetMembers = findMembers(groups, null);

    if (targetMembers.isEmpty()) {
      return ResultModel.createError(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
    }

    ConfigurationPersistenceService ccService = getConfigurationPersistenceService();

    if (groups == null) {
      groups = new String[] {"cluster"};
    }

    // Check that the specified region is in all the groups (normally we should pass in just one
    // group for alter region command
    if (ccService != null) {
      for (String group : groups) {
        CacheConfig clusterConfig = ccService.getCacheConfig(group);
        RegionConfig regionConfig = null;
        if (clusterConfig != null) {
          // we always know that regionPath starts with a "/", so we need to strip it out before we
          // pass it in to look for the regionConfig
          regionConfig =
              CacheElement.findElement(clusterConfig.getRegions(), regionPath.substring(1));
        }

        if (regionConfig == null) {
          throw new EntityNotFoundException(
              String.format("%s does not exist in group %s", regionPath, group));
        }
      }
    }

    RegionConfig deltaConfig = new RegionConfig();
    deltaConfig.setName(regionPath);
    RegionAttributesType regionAttributesType = new RegionAttributesType();
    deltaConfig.setRegionAttributes(regionAttributesType);
    regionAttributesType.setEntryIdleTime(ExpirationAttributesType.generate(entryExpirationIdleTime,
        (entryExpirationIdleTimeAction == null) ? null
            : entryExpirationIdleTimeAction.toXmlString(),
        entryIdleTimeCustomExpiry));
    regionAttributesType.setEntryTimeToLive(ExpirationAttributesType.generate(entryExpirationTTL,
        (entryExpirationTTLAction == null) ? null : entryExpirationTTLAction.toXmlString(),
        entryTTLCustomExpiry));
    regionAttributesType.setRegionIdleTime(
        ExpirationAttributesType.generate(regionExpirationIdleTime,
            (regionExpirationIdleTimeAction == null) ? null
                : regionExpirationIdleTimeAction.toXmlString(),
            null));
    regionAttributesType.setRegionTimeToLive(
        ExpirationAttributesType.generate(regionExpirationTTL,
            (regionExpirationTTLAction == null) ? null : regionExpirationTTLAction.toXmlString(),
            null));
    if (cacheLoader != null) {
      regionAttributesType.setCacheLoader(
          new DeclarableType(cacheLoader.getClassName(), cacheLoader.getInitProperties()));
    }

    if (cacheWriter != null) {
      regionAttributesType.setCacheWriter(
          new DeclarableType(cacheWriter.getClassName(), cacheWriter.getInitProperties()));
    }

    if (cacheListeners != null) {
      regionAttributesType.getCacheListeners().addAll(
          Arrays.stream(cacheListeners)
              .map(l -> new DeclarableType(l.getClassName(), l.getInitProperties()))
              .collect(Collectors.toList()));
    }

    if (gatewaySenderIds != null) {
      regionAttributesType.setGatewaySenderIds(StringUtils.join(gatewaySenderIds, ","));
    }

    if (asyncEventQueueIds != null) {
      regionAttributesType.setAsyncEventQueueIds(StringUtils.join(asyncEventQueueIds, ","));
    }

    if (cloningEnabled != null) {
      regionAttributesType.setCloningEnabled(cloningEnabled);
    }

    if (evictionMax != null && evictionMax < 0) {
      throw new IllegalArgumentException(CliStrings.format(
          CliStrings.ALTER_REGION__MSG__SPECIFY_POSITIVE_INT_FOR_EVICTIONMAX_0_IS_NOT_VALID,
          evictionMax));
    }

    if (evictionMax != null) {
      EvictionAttributes evictionAttributes =
          new EvictionAttributes();
      EvictionAttributes.LruEntryCount lruEntryCount =
          new EvictionAttributes.LruEntryCount();
      lruEntryCount.setMaximum(evictionMax.toString());
      evictionAttributes.setLruEntryCount(lruEntryCount);
      regionAttributesType.setEvictionAttributes(evictionAttributes);
    }

    List<CliFunctionResult> regionAlterResults =
        executeAndGetFunctionResult(new RegionAlterFunction(), deltaConfig, targetMembers);
    ResultModel result = ResultModel.createMemberStatusResult(regionAlterResults);
    result.setConfigObject(deltaConfig);
    return result;
  }

  @Override
  public boolean updateConfigForGroup(String group, CacheConfig cacheConfig, Object configObject) {
    RegionConfig deltaConfig = (RegionConfig) configObject;
    RegionConfig existingConfig = CacheElement.findElement(cacheConfig.getRegions(),
        deltaConfig.getId());

    RegionAttributesType deltaAttributes = deltaConfig.getRegionAttributes();
    RegionAttributesType existingAttributes = existingConfig.getRegionAttributes();

    existingAttributes.setEntryIdleTime(
        ExpirationAttributesType.combine(existingAttributes.getEntryIdleTime(),
            deltaAttributes.getEntryIdleTime()));
    existingAttributes.setEntryTimeToLive(
        ExpirationAttributesType.combine(existingAttributes.getEntryTimeToLive(),
            deltaAttributes.getEntryTimeToLive()));
    existingAttributes.setRegionIdleTime(
        ExpirationAttributesType.combine(existingAttributes.getRegionIdleTime(),
            deltaAttributes.getRegionIdleTime()));
    existingAttributes.setRegionTimeToLive(
        ExpirationAttributesType.combine(existingAttributes.getRegionTimeToLive(),
            deltaAttributes.getRegionTimeToLive()));

    if (deltaAttributes.getCacheLoader() != null) {
      if (deltaAttributes.getCacheLoader().equals(DeclarableType.EMPTY)) {
        existingAttributes.setCacheLoader(null);
      } else {
        existingAttributes.setCacheLoader(deltaAttributes.getCacheLoader());
      }
    }

    if (deltaAttributes.getCacheWriter() != null) {
      if (deltaAttributes.getCacheWriter().equals(DeclarableType.EMPTY)) {
        existingAttributes.setCacheWriter(null);
      } else {
        existingAttributes.setCacheWriter(deltaAttributes.getCacheWriter());
      }
    }

    if (!deltaAttributes.getCacheListeners().isEmpty()) {
      existingAttributes.getCacheListeners().clear();
      // only add the new cache listeners to the list when it's an EMPTY cache listener
      if (!deltaAttributes.getCacheListeners().get(0).equals(DeclarableType.EMPTY)) {
        existingAttributes.getCacheListeners().addAll(deltaAttributes.getCacheListeners());
      }
    }

    if (deltaAttributes.getGatewaySenderIds() != null) {
      existingAttributes.setGatewaySenderIds(deltaAttributes.getGatewaySenderIds());
    }

    if (deltaAttributes.getAsyncEventQueueIds() != null) {
      existingAttributes.setAsyncEventQueueIds(deltaAttributes.getAsyncEventQueueIds());
    }

    if (deltaAttributes.isCloningEnabled() != null) {
      existingAttributes.setCloningEnabled(deltaAttributes.isCloningEnabled());
    }

    EvictionAttributes evictionAttributes = deltaAttributes.getEvictionAttributes();
    if (evictionAttributes != null) {
      // we only set the max in the delta's lruEntryCount in the alter region command
      String newMax = evictionAttributes.getLruEntryCount().getMaximum();
      EvictionAttributes existingEviction = existingAttributes.getEvictionAttributes();

      // we only alter the max value if there is an existing eviction attributes
      if (existingEviction != null) {
        if (existingEviction.getLruEntryCount() != null) {
          existingEviction.getLruEntryCount().setMaximum(newMax);
        }

        if (existingEviction.getLruMemorySize() != null) {
          existingEviction.getLruMemorySize().setMaximum(newMax);
        }
      }
    }
    return true;
  }
}
