// Copyright (C) 2017 The Android Open Source Project
//
// Licensed 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 com.ericsson.gerrit.plugins.highavailability.websession.file;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.ericsson.gerrit.plugins.highavailability.Configuration;
import com.google.gerrit.server.git.WorkQueue;
import com.google.inject.Provider;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class FileBasedWebSessionCacheCleanerTest {

  private static long CLEANUP_INTERVAL = 5000;
  private static String SOME_PLUGIN_NAME = "somePluginName";

  @Mock private ScheduledThreadPoolExecutor executorMock;
  @Mock private ScheduledFuture<?> scheduledFutureMock;
  @Mock private WorkQueue workQueueMock;
  @Mock private Provider<CleanupTask> cleanupTaskProviderMock;

  @Mock(answer = Answers.RETURNS_DEEP_STUBS)
  private Configuration configMock;

  private FileBasedWebSessionCacheCleaner cleaner;

  @Before
  public void setUp() {
    when(cleanupTaskProviderMock.get()).thenReturn(new CleanupTask(null, null));
    when(workQueueMock.getDefaultQueue()).thenReturn(executorMock);
    doReturn(scheduledFutureMock)
        .when(executorMock)
        .scheduleAtFixedRate(isA(CleanupTask.class), anyLong(), anyLong(), isA(TimeUnit.class));
    when(configMock.websession().cleanupInterval()).thenReturn(CLEANUP_INTERVAL);
    cleaner =
        new FileBasedWebSessionCacheCleaner(workQueueMock, cleanupTaskProviderMock, configMock);
  }

  @Test
  public void testCleanupTaskRun() {
    FileBasedWebsessionCache cacheMock = mock(FileBasedWebsessionCache.class);
    CleanupTask task = new CleanupTask(cacheMock, null);
    int numberOfRuns = 5;
    for (int i = 0; i < numberOfRuns; i++) {
      task.run();
    }
    verify(cacheMock, times(numberOfRuns)).cleanUp();
  }

  @Test
  public void testCleanupTaskToString() {
    CleanupTask task = new CleanupTask(null, SOME_PLUGIN_NAME);
    assertThat(task.toString())
        .isEqualTo(String.format("[%s] Clean up expired file based websessions", SOME_PLUGIN_NAME));
  }

  @Test
  public void testCleanupTaskIsScheduledOnStart() {
    cleaner.start();
    verify(executorMock, times(1))
        .scheduleAtFixedRate(
            isA(CleanupTask.class), eq(1000l), eq(CLEANUP_INTERVAL), eq(TimeUnit.MILLISECONDS));
  }

  @Test
  public void testCleanupTaskIsCancelledOnStop() {
    cleaner.start();
    cleaner.stop();
    verify(scheduledFutureMock, times(1)).cancel(true);
  }

  @Test
  public void testCleanupTaskIsCancelledOnlyOnce() {
    cleaner.start();
    cleaner.stop();
    cleaner.stop();
    verify(scheduledFutureMock, times(1)).cancel(true);
  }
}
