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

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import org.apache.shiro.subject.Subject;
import org.springframework.shell.core.CommandMarker;

import org.apache.geode.annotations.Experimental;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.distributed.ConfigurationPersistenceService;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.InternalLocator;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.serialization.Version;
import org.apache.geode.management.ManagementService;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.internal.cli.CliUtil;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.shell.Gfsh;
import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
import org.apache.geode.security.ResourcePermission;

@Experimental
public abstract class GfshCommand implements CommandMarker {
  public static final String EXPERIMENTAL = "(Experimental) ";
  private InternalCache cache;


  public boolean isOnlineCommandAvailable() {
    Gfsh gfsh = Gfsh.getCurrentInstance();
    // command should always be available on the server
    if (gfsh == null) {
      return true;
    }
    // if in gfshVM, only when gfsh is connected and ready
    return gfsh.isConnectedAndReady();
  }

  public void authorize(ResourcePermission.Resource resource,
      ResourcePermission.Operation operation, ResourcePermission.Target target) {
    cache.getSecurityService().authorize(resource, operation, target);
  }

  public void authorize(ResourcePermission.Resource resource,
      ResourcePermission.Operation operation, String target) {
    cache.getSecurityService().authorize(resource, operation, target);
  }

  public void authorize(ResourcePermission.Resource resource,
      ResourcePermission.Operation operation, String target, String key) {
    cache.getSecurityService().authorize(resource, operation, target, key);
  }

  public Cache getCache() {
    if (cache == null) {
      return null;
    }
    return cache.getCacheForProcessingClientRequests();
  }

  public <T extends ManagementService> T getManagementService() {
    return (T) ManagementService.getExistingManagementService(cache);
  }

  public <T extends ConfigurationPersistenceService> T getConfigurationPersistenceService() {
    InternalLocator locator = InternalLocator.getLocator();
    return locator == null ? null : (T) locator.getConfigurationPersistenceService();
  }

  public ClusterManagementService getClusterManagementService() {
    InternalLocator locator = InternalLocator.getLocator();
    return locator == null ? null : locator.getClusterManagementService();
  }

  public void setCache(Cache cache) {
    this.cache = (InternalCache) cache;
  }

  public boolean isSharedConfigurationRunning() {
    InternalLocator locator = InternalLocator.getLocator();
    return locator != null && locator.isSharedConfigurationRunning();
  }

  public Subject getSubject() {
    return cache.getSecurityService().getSubject();
  }

  /**
   * this either returns a non-null member or throw an exception if member is not found.
   */
  public DistributedMember getMember(final String memberName) {
    DistributedMember member = findMember(memberName);

    if (member == null) {
      throw new EntityNotFoundException(
          CliStrings.format(CliStrings.MEMBER_NOT_FOUND_ERROR_MESSAGE, memberName));
    }
    return member;
  }

  /**
   * this will return the member found or null if no member with that name
   */
  public DistributedMember findMember(final String memberName) {
    return CliUtil.getDistributedMemberByNameOrId(memberName, (InternalCache) getCache());
  }

  /**
   * Gets all members in the GemFire distributed system/cache, including locators
   */
  public Set<DistributedMember> getAllMembers() {
    return CliUtil.getAllMembers(cache);
  }

  /**
   * Get All members, excluding locators
   */
  public Set<DistributedMember> getAllNormalMembers() {
    return CliUtil.getAllNormalMembers(cache);
  }

  /**
   * Get All members >= a specific version, excluding locators
   */
  public Set<DistributedMember> getNormalMembersWithSameOrNewerVersion(Version version) {
    return CliUtil.getNormalMembersWithSameOrNewerVersion(cache, version);
  }

  public Execution getMembersFunctionExecutor(final Set<DistributedMember> members) {
    return FunctionService.onMembers(members);
  }

  /**
   * if no members matches these names, an empty set would return, this does not include locators
   */
  public Set<DistributedMember> findMembers(String[] groups, String[] members) {
    return CliUtil.findMembers(groups, members, cache);
  }

  /**
   * if no members matches these names, a UserErrorException will be thrown
   */
  public Set<DistributedMember> getMembers(String[] groups, String[] members) {
    Set<DistributedMember> matchingMembers = findMembers(groups, members);
    if (matchingMembers.size() == 0) {
      throw new EntityNotFoundException(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
    }
    return matchingMembers;
  }

  /**
   * if no members matches these names, an empty set would return
   */
  public Set<DistributedMember> findMembersIncludingLocators(String[] groups, String[] members) {
    return CliUtil.findMembersIncludingLocators(groups, members, (InternalCache) getCache());
  }

  /**
   * if no members matches these names, a UserErrorException will be thrown
   */
  public Set<DistributedMember> getMembersIncludingLocators(String[] groups, String[] members) {
    Set<DistributedMember> matchingMembers = findMembersIncludingLocators(groups, members);
    if (matchingMembers.size() == 0) {
      throw new EntityNotFoundException(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
    }
    return matchingMembers;
  }

  public Set<DistributedMember> findMembersForRegion(String regionPath) {
    return CliUtil.getRegionAssociatedMembers(regionPath, cache, true);
  }

  public Set<DistributedMember> findAnyMembersForRegion(String regionPath) {
    return CliUtil.getRegionAssociatedMembers(regionPath, cache, false);
  }

  public ResultCollector<?, ?> executeFunction(Function function, Object args,
      final Set<DistributedMember> targetMembers) {
    return CliUtil.executeFunction(function, args, targetMembers);
  }

  public ResultCollector<?, ?> executeFunction(Function function, Object args,
      final DistributedMember targetMember) {
    return executeFunction(function, args, Collections.singleton(targetMember));
  }

  public CliFunctionResult executeFunctionAndGetFunctionResult(Function function, Object args,
      final DistributedMember targetMember) {
    ResultCollector rc = executeFunction(function, args, Collections.singleton(targetMember));
    List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
    return results.size() > 0 ? results.get(0) : null;
  }

  public List<CliFunctionResult> executeAndGetFunctionResult(Function function, Object args,
      Set<DistributedMember> targetMembers) {
    ResultCollector rc = executeFunction(function, args, targetMembers);
    return CliFunctionResult.cleanResults((List<?>) rc.getResult());
  }

  /**
   * Very basic polling functionality that executes a function until it returns true or the timeout
   * is reached. The polling call is performed on the calling thread. Do not use it with a
   * function that may have an unbounded runtime. The timeout is very coarse and will not account
   * for the function overrunning the given time.
   *
   * @param function a {@link Supplier Supplier&lt;Boolean&gt;} function that will poll for the
   *        condition
   * @return true if the function returns true within the timeout period; false otherwise
   */
  public boolean poll(long timeout, TimeUnit unit, Supplier<Boolean> function) {
    long startWaitTime = System.currentTimeMillis();
    long waitTime = unit.toMillis(timeout);

    do {
      try {
        if (function.get()) {
          return true;
        }

        Thread.sleep(100);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return false;
      }
    } while (System.currentTimeMillis() - startWaitTime < waitTime);

    return false;

  }
}
