// Copyright (C) 2015 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 com.google.common.collect.ImmutableMap;
import com.google.gerrit.httpd.WebSessionManager.Val;

import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

public class FileBasedWebSessionCacheTest {

  private static final String EXISTING_KEY = "aSceprtBc02YaMY573T5jfW64ZudJfPbDq";
  private static final String EMPTY_KEY = "aOc2prqlZRpSO3LpauGO5efCLs1L9r9KkG";
  private static final String INVALID_KEY = "aOFdpHriBM6dN055M13PjDdTZagl5r5aSG";

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  private FileBasedWebsessionCache cache;
  private Path websessionDir;

  @Before
  public void setUp() throws Exception {
    websessionDir = tempFolder.newFolder("websessions").toPath();
    cache = new FileBasedWebsessionCache(tempFolder.getRoot().toPath());
  }

  @Test
  public void asMapTest() throws Exception {
    loadKeyToCacheDir(EMPTY_KEY);
    assertThat(cache.asMap()).isEmpty();

    loadKeyToCacheDir(INVALID_KEY);
    assertThat(cache.asMap()).isEmpty();

    loadKeyToCacheDir(EXISTING_KEY);
    assertThat(cache.asMap()).containsKey(EXISTING_KEY);
  }

  @Test
  public void constructorCreateDir() throws IOException {
    assertThat(websessionDir.toFile().delete()).isTrue();
    cache = new FileBasedWebsessionCache(tempFolder.getRoot().toPath());
    assertThat(websessionDir.toFile().exists()).isTrue();
  }

  @Test
  public void cleanUpTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    try {
      long existingKeyExpireAt =
          cache.getIfPresent(EXISTING_KEY).getExpiresAt();
      DateTimeUtils.setCurrentMillisFixed(
          new DateTime(existingKeyExpireAt).minusHours(1).getMillis());
      cache.cleanUp();
      assertThat(isDirEmpty(websessionDir)).isFalse();

      DateTimeUtils.setCurrentMillisFixed(
          new DateTime(existingKeyExpireAt).plusHours(1).getMillis());
      cache.cleanUp();
      assertThat(isDirEmpty(websessionDir)).isTrue();
    } finally {
      DateTimeUtils.setCurrentMillisSystem();
    }
  }

  @Test
  public void cleanUpWithErrorsWhileListingFilesTest() throws Exception {
    tempFolder.delete();
    cache.cleanUp();
    assertThat(cache.size()).isEqualTo(0);
  }

  @Test
  public void cleanUpWithErrorsWhileDeleteFileTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    try {
      websessionDir.toFile().setWritable(false);
      cache.cleanUp();
      assertThat(cache.size()).isEqualTo(1);
    } finally {
      websessionDir.toFile().setWritable(true);
    }
  }

  @Test
  public void getIfPresentEmptyKeyTest() throws Exception {
    assertThat(cache.getIfPresent(EMPTY_KEY)).isNull();
  }

  @Test
  public void getIfPresentObjectNonStringTest() throws Exception {
    assertThat(cache.getIfPresent(new Object())).isNull();
  }

  @Test
  public void getIfPresentInvalidKeyTest() throws Exception {
    loadKeyToCacheDir(INVALID_KEY);
    Path path = websessionDir.resolve(INVALID_KEY);
    assertThat(cache.getIfPresent(path)).isNull();
  }

  @Test
  public void getIfPresentTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    assertThat(cache.getIfPresent(EXISTING_KEY)).isNotNull();
  }

  @Test
  public void getAllPresentTest() throws Exception {
    loadKeyToCacheDir(EMPTY_KEY);
    loadKeyToCacheDir(INVALID_KEY);
    loadKeyToCacheDir(EXISTING_KEY);
    List<String> keys =
        Arrays.asList(new String[] {EMPTY_KEY, EXISTING_KEY});
    assertThat(cache.getAllPresent(keys).size()).isEqualTo(1);
    assertThat(cache.getAllPresent(keys)).containsKey(EXISTING_KEY);
  }

  @Test
  public void getTest() throws Exception {
    class ValueLoader implements Callable<Val> {
      @Override
      public Val call() throws Exception {
        return null;
      }
    }
    assertThat(cache.get(EXISTING_KEY, new ValueLoader())).isNull();

    loadKeyToCacheDir(EXISTING_KEY);
    assertThat(cache.get(EXISTING_KEY, new ValueLoader())).isNotNull();
  }

  @Test(expected = ExecutionException.class)
  public void getTestCallableThrowsException() throws Exception {
    class ValueLoader implements Callable<Val> {
      @Override
      public Val call() throws Exception {
        throw new Exception();
      }
    }
    assertThat(cache.get(EXISTING_KEY, new ValueLoader())).isNull();
  }

  @Test
  public void invalidateAllCollectionTest() throws Exception {
    int numberOfKeys = 15;
    List<String> keys = loadKeysToCacheDir(numberOfKeys);
    assertThat(cache.size()).isEqualTo(numberOfKeys);
    assertThat(isDirEmpty(websessionDir)).isFalse();

    cache.invalidateAll(keys);
    assertThat(cache.size()).isEqualTo(0);
    assertThat(isDirEmpty(websessionDir)).isTrue();
  }

  @Test
  public void invalidateAllTest() throws Exception {
    int numberOfKeys = 5;
    loadKeysToCacheDir(numberOfKeys);
    assertThat(cache.size()).isEqualTo(numberOfKeys);
    assertThat(isDirEmpty(websessionDir)).isFalse();

    cache.invalidateAll();
    assertThat(cache.size()).isEqualTo(0);
    assertThat(isDirEmpty(websessionDir)).isTrue();
  }

  @Test
  public void invalidateTest() throws Exception {
    Path fileToDelete = Files.createFile(websessionDir.resolve(EXISTING_KEY));
    assertThat(Files.exists(fileToDelete)).isTrue();
    cache.invalidate(EXISTING_KEY);
    assertThat(Files.exists(fileToDelete)).isFalse();
  }

  @Test
  public void invalidateTestObjectNotString() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    assertThat(cache.size()).isEqualTo(1);
    cache.invalidate(new Object());
    assertThat(cache.size()).isEqualTo(1);
  }

  @Test
  public void putTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    Val val = cache.getIfPresent(EXISTING_KEY);
    String newKey = "abcde12345";
    cache.put(newKey, val);
    assertThat(cache.getIfPresent(newKey)).isNotNull();
  }

  @Test
  public void putAllTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    Val val = cache.getIfPresent(EXISTING_KEY);
    String newKey = "abcde12345";
    Map<String, Val> sessions = ImmutableMap.of(newKey, val);
    cache.putAll(sessions);
    assertThat(cache.asMap()).containsKey(newKey);
  }

  @Test
  public void putWithErrorsTest() throws Exception {
    loadKeyToCacheDir(EXISTING_KEY);
    Val val = cache.getIfPresent(EXISTING_KEY);
    String newKey = "abcde12345";
    tempFolder.delete();
    cache.put(newKey, val);
    assertThat(cache.getIfPresent(newKey)).isNull();
  }

  @Test
  public void sizeTest() throws Exception {
    int numberOfKeys = 10;
    loadKeysToCacheDir(numberOfKeys);
    assertThat(cache.size()).isEqualTo(numberOfKeys);
  }

  @Test
  public void statTest() throws Exception {
    assertThat(cache.stats()).isNull();
  }

  private List<String> loadKeysToCacheDir(int number) throws IOException {
    List<String> keys = new ArrayList<>();
    for (int i = 0; i < number; i++) {
      Path tmp = Files.createTempFile(websessionDir, "cache", null);
      keys.add(tmp.getFileName().toString());
    }
    return keys;
  }

  private boolean isDirEmpty(final Path dir) throws IOException {
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir)) {
      return !dirStream.iterator().hasNext();
    }
  }

  private Path loadKeyToCacheDir(String key) throws IOException {
    if(key.equals(EMPTY_KEY)){
      return Files.createFile(websessionDir.resolve(EMPTY_KEY));
    }
    InputStream in = loadFile(key);
    Path target = websessionDir.resolve(key);
    Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
    return target;
  }

  private InputStream loadFile(String file) {
    return this.getClass().getResourceAsStream("/" + file);
  }
}
