/*
 * 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.configuration.validators;


import org.apache.commons.lang3.StringUtils;

import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
import org.apache.geode.cache.configuration.RegionAttributesDataPolicy;
import org.apache.geode.cache.configuration.RegionAttributesScope;
import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.RegionNameValidation;
import org.apache.geode.management.internal.CacheElementOperation;
import org.apache.geode.security.ResourcePermission;

public class RegionConfigValidator implements ConfigurationValidator<RegionConfig> {
  private InternalCache cache;

  public RegionConfigValidator(InternalCache cache) {
    this.cache = cache;
  }

  @Override
  public void validate(CacheElementOperation operation, RegionConfig config)
      throws IllegalArgumentException {
    switch (operation) {
      case UPDATE:
      case CREATE:
        validateCreate(config);
        break;
      case DELETE:
        validateDelete(config);
      default:
    }
  }

  private void validateDelete(CacheElement config) {
    if (StringUtils.isNotBlank(config.getGroup())) {
      throw new IllegalArgumentException(
          "Group is an invalid option when deleting region.");
    }
  }

  private void validateCreate(RegionConfig config) {
    if (config.getType() == null) {
      throw new IllegalArgumentException("Region type is required.");
    }

    // validate if the type is a valid RegionType. Only types defined in RegionType are supported
    // by management v2 api.
    try {
      RegionType.valueOf(config.getType());
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(
          String.format("Region type '%s' is not supported.", config.getType()));
    }

    RegionNameValidation.validate(config.getName());

    setShortcutAttributes(config);

    // additional authorization
    if (config.getRegionAttributes().getDataPolicy().isPersistent()) {
      cache.getSecurityService()
          .authorize(ResourcePermission.Resource.CLUSTER, ResourcePermission.Operation.WRITE,
              ResourcePermission.Target.DISK);
    }
  }

  public static void setShortcutAttributes(RegionConfig config) {
    String type = config.getType();
    RegionAttributesType regionAttributes;

    if (config.getRegionAttributes() == null) {
      regionAttributes = new RegionAttributesType();
      config.setRegionAttributes(regionAttributes);
    }

    regionAttributes = config.getRegionAttributes();
    switch (type) {
      case "PARTITION": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        break;
      }
      case "REPLICATE": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        break;
      }
      case "PARTITION_REDUNDANT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        break;
      }
      case "PARTITION_PERSISTENT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION, regionAttributes);
        break;
      }
      case "PARTITION_REDUNDANT_PERSISTENT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION, regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        break;
      }
      case "PARTITION_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "PARTITION_REDUNDANT_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "PARTITION_PERSISTENT_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "PARTITION_REDUNDANT_PERSISTENT_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_PARTITION, regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "PARTITION_HEAP_LRU": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.LOCAL_DESTROY, regionAttributes);
        break;

      }
      case "PARTITION_REDUNDANT_HEAP_LRU": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.LOCAL_DESTROY, regionAttributes);
        break;
      }

      case "REPLICATE_PERSISTENT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        break;
      }
      case "REPLICATE_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;

      }
      case "REPLICATE_PERSISTENT_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "REPLICATE_HEAP_LRU": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PRELOADED, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        regionAttributes.setInterestPolicy("all");
        checkAndSetEvictionAction(EnumActionDestroyOverflow.LOCAL_DESTROY, regionAttributes);
        break;
      }
      case "LOCAL": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.NORMAL, regionAttributes);
        checkAndSetScope(RegionAttributesScope.LOCAL, regionAttributes);
        break;
      }
      case "LOCAL_PERSISTENT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.LOCAL, regionAttributes);
        break;
      }
      case "LOCAL_HEAP_LRU": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.NORMAL, regionAttributes);
        checkAndSetScope(RegionAttributesScope.LOCAL, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.LOCAL_DESTROY, regionAttributes);
        break;
      }
      case "LOCAL_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.NORMAL, regionAttributes);
        checkAndSetScope(RegionAttributesScope.LOCAL, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "LOCAL_PERSISTENT_OVERFLOW": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PERSISTENT_REPLICATE, regionAttributes);
        checkAndSetScope(RegionAttributesScope.LOCAL, regionAttributes);
        checkAndSetEvictionAction(EnumActionDestroyOverflow.OVERFLOW_TO_DISK, regionAttributes);
        break;
      }
      case "PARTITION_PROXY": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetLocalMaxMemory("0", regionAttributes);
        break;
      }
      case "PARTITION_PROXY_REDUNDANT": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.PARTITION, regionAttributes);
        checkAndSetLocalMaxMemory("0", regionAttributes);
        checkAndSetRedundancyCopy("1", regionAttributes);
        break;
      }
      case "REPLICATE_PROXY": {
        checkAndSetDataPolicy(RegionAttributesDataPolicy.EMPTY, regionAttributes);
        checkAndSetScope(RegionAttributesScope.DISTRIBUTED_ACK, regionAttributes);
        break;
      }
      default:
        throw new IllegalArgumentException("Invalid type " + type + ".");
    }
  }

  private static void checkAndSetLocalMaxMemory(String maxMemory,
      RegionAttributesType regionAttributes) {
    if (regionAttributes.getPartitionAttributes() == null
        || regionAttributes.getPartitionAttributes().getLocalMaxMemory() == null) {
      regionAttributes.setLocalMaxMemory(maxMemory);
    }
    String existing = regionAttributes.getPartitionAttributes().getLocalMaxMemory();
    if (!existing.equals(maxMemory)) {
      throw new IllegalArgumentException("Invalid local max memory: " + existing + ".");
    }
  }

  private static void checkAndSetEvictionAction(EnumActionDestroyOverflow evictionAction,
      RegionAttributesType regionAttributes) {
    if (regionAttributes.getEvictionAttributes() == null
        || regionAttributes.getEvictionAttributes().getLruHeapPercentage() == null
        || regionAttributes.getEvictionAttributes().getLruHeapPercentage().getAction() == null) {
      regionAttributes.setLruHeapPercentageEvictionAction(evictionAction);
    }

    EnumActionDestroyOverflow existing =
        regionAttributes.getEvictionAttributes().getLruHeapPercentage().getAction();
    if (existing != evictionAction) {
      throw new IllegalArgumentException(
          "Conflicting eviction action " + existing.toString() + ".");
    }
  }

  private static void checkAndSetScope(RegionAttributesScope scope,
      RegionAttributesType regionAttributes) {
    RegionAttributesScope existing = regionAttributes.getScope();
    if (existing == null) {
      regionAttributes.setScope(scope);
    } else if (existing != scope) {
      throw new IllegalArgumentException("Conflicting scope " + existing.toString() + ".");
    }
  }

  private static void checkAndSetDataPolicy(RegionAttributesDataPolicy policy,
      RegionAttributesType regionAttributes) {
    RegionAttributesDataPolicy existing = regionAttributes.getDataPolicy();
    if (existing == null) {
      regionAttributes.setDataPolicy(policy);
    } else if (existing != policy) {
      throw new IllegalArgumentException("Conflicting data policy "
          + existing.toString() + ".");
    }
  }

  // need to do this if user already set the redundant copy in the RegionAttributeType
  private static void checkAndSetRedundancyCopy(String copies,
      RegionAttributesType regionAttributes) {
    if (regionAttributes.getPartitionAttributes() == null
        || regionAttributes.getPartitionAttributes().getRedundantCopies() == null) {
      regionAttributes.setRedundantCopy(copies);
    }
    RegionAttributesType.PartitionAttributes partitionAttributes =
        regionAttributes.getPartitionAttributes();
    if ("0".equals(partitionAttributes.getRedundantCopies())) {
      throw new IllegalArgumentException(
          "Conflicting redundant copy when region type is REDUNDANT.");
    }
  }
}
