/*
 * 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.cache.client.internal;

import static org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.FUNCTION_HAS_RESULT;
import static org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.FUNCTION_NAME;
import static org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.OPTIMIZE_FOR_WRITE_SETTING;
import static org.apache.geode.internal.cache.execute.AbstractExecution.DEFAULT_CLIENT_FUNCTION_TIMEOUT;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import junitparams.naming.TestCaseName;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;

import org.apache.geode.cache.client.ServerConnectivityException;
import org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.FailureMode;
import org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.FunctionIdentifierType;
import org.apache.geode.cache.client.internal.ExecuteFunctionTestSupport.HAStatus;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.distributed.internal.ServerLocation;
import org.apache.geode.internal.cache.execute.ServerRegionFunctionExecutor;
import org.apache.geode.test.junit.categories.ClientServerTest;

/**
 * Test retry counts on single-hop onRegion() function execution (via
 * ExecuteRegionFunctionSingleHop).
 * Ensure they are never infinite!
 */
@Category({ClientServerTest.class})
@RunWith(JUnitParamsRunner.class)

public class ExecuteRegionFunctionSingleHopOpRetryTest {

  private Map<ServerLocation, HashSet<Integer>> serverToFilterMap;
  private ExecuteFunctionTestSupport testSupport;

  @Test
  @Parameters({
      "NOT_HA, OBJECT_REFERENCE, -1, 2",
      "NOT_HA, OBJECT_REFERENCE, 0, 2",
      "NOT_HA, OBJECT_REFERENCE, 3, 2",
      "NOT_HA, STRING, -1, 2",
      "NOT_HA, STRING, 0, 2",
      "NOT_HA, STRING, 3, 2",
      "HA, OBJECT_REFERENCE, -1, 2",
      "HA, OBJECT_REFERENCE, 0, 2",
      "HA, OBJECT_REFERENCE, 3, 2",
      "HA, STRING, -1, 2",
      "HA, STRING, 0, 2",
      "HA, STRING, 3, 2",
  })
  @TestCaseName("[{index}] {method}: {params}")
  public void executeDoesNotRetryOnServerOperationException(
      final HAStatus haStatus,
      final FunctionIdentifierType functionIdentifierType,
      final int retryAttempts,
      final int expectTries) {

    runExecuteTest(haStatus, functionIdentifierType, retryAttempts, expectTries,
        FailureMode.THROW_SERVER_OPERATION_EXCEPTION);
  }

  @Test
  @Parameters({
      "NOT_HA, OBJECT_REFERENCE, -1, 2",
      "NOT_HA, OBJECT_REFERENCE, 0, 2",
      "NOT_HA, OBJECT_REFERENCE, 3, 2",
      "NOT_HA, STRING, -1, 2",
      "NOT_HA, STRING, 0, 2",
      "NOT_HA, STRING, 3, 2",
      "HA, OBJECT_REFERENCE, -1, 2",
      "HA, OBJECT_REFERENCE, 0, 2",
      "HA, OBJECT_REFERENCE, 3, 2",
      "HA, STRING, -1, 2",
      "HA, STRING, 0, 2",
      "HA, STRING, 3, 2",
  })
  @TestCaseName("[{index}] {method}: {params}")
  public void executeDoesNotRetryOnNoServerAvailableException(
      final HAStatus haStatus,
      final FunctionIdentifierType functionIdentifierType,
      final int retryAttempts,
      final int expectTries) {

    runExecuteTest(haStatus, functionIdentifierType, retryAttempts, expectTries,
        FailureMode.THROW_NO_AVAILABLE_SERVERS_EXCEPTION);
  }

  @Test
  @Parameters({
      "NOT_HA, OBJECT_REFERENCE, -1, 2",
      "NOT_HA, OBJECT_REFERENCE, 0, 2",
      "NOT_HA, OBJECT_REFERENCE, 3, 2",
      "NOT_HA, STRING, -1, 2",
      "NOT_HA, STRING, 0, 2",
      "NOT_HA, STRING, 3, 2",
      "HA, OBJECT_REFERENCE, -1, 2",
      "HA, OBJECT_REFERENCE, 0, 2",
      "HA, OBJECT_REFERENCE, 3, 2",
      "HA, STRING, -1, 2",
      "HA, STRING, 0, 2",
      "HA, STRING, 3, 2",
  })
  @TestCaseName("[{index}] {method}: {params}")
  public void executeWithServerConnectivityException(
      final HAStatus haStatus,
      final FunctionIdentifierType functionIdentifierType,
      final int retryAttempts,
      final int expectTries) {

    runExecuteTest(haStatus, functionIdentifierType, retryAttempts, expectTries,
        FailureMode.THROW_SERVER_CONNECTIVITY_EXCEPTION);
  }

  private void createMocks(final HAStatus haStatus,
      final FailureMode failureModeArg) {

    testSupport = new ExecuteFunctionTestSupport(haStatus, failureModeArg,
        (pool, failureMode) -> ExecuteFunctionTestSupport.thenThrow(when(
            pool.executeOn(
                ArgumentMatchers.any(),
                ArgumentMatchers.any(),
                ArgumentMatchers.anyBoolean(),
                ArgumentMatchers.anyBoolean())),
            failureMode));

    serverToFilterMap = new HashMap<>();
    serverToFilterMap.put(new ServerLocation("host1", 10), new HashSet<>());
    serverToFilterMap.put(new ServerLocation("host2", 10), new HashSet<>());
  }

  private void runExecuteTest(final HAStatus haStatus,
      final FunctionIdentifierType functionIdentifierType,
      final int retryAttempts, final int expectTries,
      final FailureMode failureMode) {

    createMocks(haStatus, failureMode);

    executeFunctionSingleHopAndValidate(haStatus, functionIdentifierType, retryAttempts,
        testSupport.getExecutablePool(),
        testSupport.getFunction(),
        testSupport.getExecutor(), testSupport.getResultCollector(), expectTries);
  }

  private void executeFunctionSingleHopAndValidate(
      final HAStatus haStatus,
      final FunctionIdentifierType functionIdentifierType,
      final int retryAttempts,
      final PoolImpl executablePool,
      final Function<Integer> function,
      final ServerRegionFunctionExecutor executor,
      final ResultCollector<Integer, Collection<Integer>> resultCollector,
      final int expectTries) {

    switch (functionIdentifierType) {
      case STRING:
        ignoreServerConnectivityException(
            () -> ignoreServerConnectivityException(() -> ExecuteRegionFunctionSingleHopOp.execute(
                executablePool, testSupport.getRegion(),
                executor, resultCollector, serverToFilterMap,
                retryAttempts,
                testSupport.toBoolean(haStatus),
                executor1 -> new ExecuteRegionFunctionSingleHopOp.ExecuteRegionFunctionSingleHopOpImpl(
                    testSupport.getRegion().getFullPath(), FUNCTION_NAME,
                    executor1, resultCollector,
                    FUNCTION_HAS_RESULT, new HashSet<>(),
                    ExecuteFunctionTestSupport.ALL_BUCKETS_SETTING, testSupport.toBoolean(haStatus),
                    OPTIMIZE_FOR_WRITE_SETTING, DEFAULT_CLIENT_FUNCTION_TIMEOUT),
                () -> new ExecuteRegionFunctionOp.ExecuteRegionFunctionOpImpl(
                    testSupport.getRegion().getFullPath(), FUNCTION_NAME,
                    executor, resultCollector, FUNCTION_HAS_RESULT, testSupport.toBoolean(haStatus),
                    OPTIMIZE_FOR_WRITE_SETTING, true, DEFAULT_CLIENT_FUNCTION_TIMEOUT))));
        break;
      case OBJECT_REFERENCE:
        ignoreServerConnectivityException(
            () -> ExecuteRegionFunctionSingleHopOp.execute(executablePool, testSupport.getRegion(),
                executor, resultCollector, serverToFilterMap,
                retryAttempts,
                function.isHA(),
                executor1 -> new ExecuteRegionFunctionSingleHopOp.ExecuteRegionFunctionSingleHopOpImpl(
                    testSupport.getRegion().getFullPath(), function,
                    executor1, resultCollector,
                    FUNCTION_HAS_RESULT, new HashSet<>(),
                    ExecuteFunctionTestSupport.ALL_BUCKETS_SETTING,
                    DEFAULT_CLIENT_FUNCTION_TIMEOUT),
                () -> new ExecuteRegionFunctionOp.ExecuteRegionFunctionOpImpl(
                    testSupport.getRegion().getFullPath(), function,
                    executor, resultCollector, DEFAULT_CLIENT_FUNCTION_TIMEOUT)));
        break;
      default:
        throw new AssertionError("unknown FunctionIdentifierType type: " + functionIdentifierType);
    }

    verify(executablePool, times(expectTries))
        .executeOn(
            ArgumentMatchers.any(),
            ArgumentMatchers.any(),
            ArgumentMatchers.anyBoolean(),
            ArgumentMatchers.anyBoolean());
  }

  /*
   * We could be pedantic about this exception but that's not the purpose of the retryTest()
   */
  private void ignoreServerConnectivityException(final Runnable runnable) {
    try {
      runnable.run();
    } catch (final ServerConnectivityException ignored) {
    }
  }

}
