/*
 * 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.modules.session.catalina;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.junit.Before;
import org.junit.Test;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.execute.FunctionException;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.modules.session.catalina.callback.SessionExpirationCacheListener;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.SessionCustomExpiry;
import org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction;
import org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction;

public class PeerToPeerSessionCacheJUnitTest extends AbstractSessionCacheJUnitTest {

  private String localRegionName = sessionRegionName + "_local";
  @SuppressWarnings("unchecked")
  private RegionFactory<String, HttpSession> regionFactory = mock(RegionFactory.class);
  @SuppressWarnings("unchecked")
  private Region<String, HttpSession> localRegion = mock(Region.class);
  private Cache cache = mock(Cache.class);

  @Before
  public void setUp() {
    sessionCache = spy(new PeerToPeerSessionCache(sessionManager, cache));
    doReturn(sessionRegion).when((PeerToPeerSessionCache) sessionCache)
        .createRegionUsingHelper(any(RegionConfiguration.class));
    doReturn(true).when((PeerToPeerSessionCache) sessionCache)
        .isFunctionRegistered(any(String.class));

    when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
    when(sessionManager.getLogger()).thenReturn(logger);
    when(sessionManager.getEnableLocalCache()).thenReturn(true);
    when(sessionManager.getMaxInactiveInterval())
        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL);

    when(sessionRegion.getName()).thenReturn(sessionRegionName);

    doReturn(regionFactory).when(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
    when(regionFactory.create(localRegionName)).thenReturn(localRegion);

    when(cache.getDistributedSystem()).thenReturn(distributedSystem);
  }

  @Test
  public void initializeSessionCacheSucceeds() {
    sessionCache.initialize();

    verify(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
    verify(regionFactory).create(localRegionName);
    verify((PeerToPeerSessionCache) sessionCache)
        .createRegionUsingHelper(any(RegionConfiguration.class));
    verify(regionFactory, times(0)).setStatisticsEnabled(true);
    verify(regionFactory, times(0)).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
    verify(regionFactory, times(0)).addCacheListener(any(SessionExpirationCacheListener.class));
  }

  @Test
  public void functionRegistrationDoesNotThrowException() {
    doReturn(false).when((PeerToPeerSessionCache) sessionCache)
        .isFunctionRegistered(any(String.class));

    sessionCache.initialize();

    verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
        TouchPartitionedRegionEntriesFunction.class));
    verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
        TouchReplicatedRegionEntriesFunction.class));
  }

  @Test
  public void initializeSessionCacheSucceedsWhenSessionRegionAlreadyExists() {
    doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
    doNothing().when((PeerToPeerSessionCache) sessionCache)
        .validateRegionUsingRegionhelper(any(RegionConfiguration.class), any(Region.class));

    sessionCache.initialize();

    verify((PeerToPeerSessionCache) sessionCache, times(0))
        .createRegionUsingHelper(any(RegionConfiguration.class));
  }

  @Test
  public void nonDefaultMaxTimeoutIntervalSetsExpirationDetails() {
    // Setting the mocked return value of getMaxInactiveInterval to something distinctly not equal
    // to the default
    when(sessionManager.getMaxInactiveInterval())
        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL + 1);

    sessionCache.initialize();

    verify(regionFactory).setStatisticsEnabled(true);
    verify(regionFactory).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
    verify(regionFactory).addCacheListener(any(SessionExpirationCacheListener.class));
  }

  @Test
  public void initializeSessionCacheSucceedsWhenLocalRegionAlreadyExists() {
    doReturn(localRegion).when(cache).getRegion(localRegionName);

    sessionCache.initialize();

    verify(regionFactory, times(0)).create(any(String.class));
  }


  @Test
  public void operationRegionIsCorrectlySetWhenEnableLocalCachingIsFalse() {
    when(sessionManager.getEnableLocalCache()).thenReturn(false);

    sessionCache.initialize();

    verify(cache, times(0)).getRegion(localRegionName);
    assertThat(sessionCache.sessionRegion).isEqualTo(sessionCache.operatingRegion);
  }

  @Test
  public void touchSessionsWithPartitionedRegionSucceeds() {
    Set<String> sessionIds = new HashSet<>();
    ResultCollector collector = mock(ResultCollector.class);

    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
        .getExecutionForFunctionOnRegionWithFilter(sessionIds);
    when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);

    sessionCache.touchSessions(sessionIds);

    verify(emptyExecution).execute(TouchPartitionedRegionEntriesFunction.ID);
    verify(collector).getResult();
  }

  @Test
  public void touchSessionsWithReplicatedRegionSucceeds() {
    // Need to invoke this to set the session region
    sessionCache.initialize();

    Set<String> sessionIds = new HashSet<>();
    ResultCollector collector = mock(ResultCollector.class);

    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.REPLICATE.toString());
    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
        .getExecutionForFunctionOnMembersWithArguments(any(Object[].class));
    when(emptyExecution.execute(TouchReplicatedRegionEntriesFunction.ID)).thenReturn(collector);

    sessionCache.touchSessions(sessionIds);

    verify(emptyExecution).execute(TouchReplicatedRegionEntriesFunction.ID);
    verify(collector).getResult();
  }

  @Test
  public void touchSessionsCatchesThrownException() {
    Set<String> sessionIds = new HashSet<>();
    ResultCollector collector = mock(ResultCollector.class);
    FunctionException exception = new FunctionException();

    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
        .getExecutionForFunctionOnRegionWithFilter(sessionIds);
    when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);
    doThrow(exception).when(collector).getResult();

    sessionCache.touchSessions(sessionIds);

    verify(logger).warn("Caught unexpected exception:", exception);
  }
}
