// 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.googlesource.gerrit.plugins.websession.flatfile;

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.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.git.WorkQueue.Executor;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.websession.flatfile.FlatFileWebSessionCacheCleaner.CleanupTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class FlatFileWebSessionCacheCleanerTest {

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

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

  private FlatFileWebSessionCacheCleaner 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));
    cleaner =
        new FlatFileWebSessionCacheCleaner(
            workQueueMock, cleanupTaskProviderMock, CLEANUP_INTERVAL);
  }

  @Test
  public void testCleanupTaskRun() {
    FlatFileWebSessionCache cacheMock = mock(FlatFileWebSessionCache.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);
  }
}
