// 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.events.fsstore;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class FsStoreTest extends TestCase {
  public static String dir = "events-FsStore";
  public static Path base;

  public Path myBase;
  public FsStore store;
  public String id = UUID.randomUUID().toString();
  public String submitMarker = "";
  public long count = 1000;

  public Map<String, Long> reported = new HashMap<String, Long>();

  @Override
  @Before
  public void setUp() throws Exception {
    myBase = base;
    if (myBase == null) {
      myBase = Files.createTempDirectory(dir);
    }
    store = new FsStore(myBase);
  }

  @After
  public void tearDown() throws Exception {
    Fs.tryRecursiveDelete(myBase);
  }

  @Test
  public void testUUIDInit() throws IOException {
    UUID uuid = store.getUuid();
    FsStore store2 = new FsStore(myBase);
    assertEquals(uuid, store2.getUuid());
  }

  @Test
  public void testHeadInit() throws IOException {
    assertEquals(0, store.getHead());
    FsStore store2 = new FsStore(myBase);
    assertEquals(0, store2.getHead());
  }

  @Test
  public void testTailInit() throws IOException {
    assertEquals(0, store.getTail());
    FsStore store2 = new FsStore(myBase);
    assertEquals(0, store2.getTail());
  }

  @Test
  public void testGetInit() throws IOException {
    assertEquals(null, store.get(1));
  }

  @Test
  public void testAdd() throws IOException {
    add();
  }

  public void add() throws IOException {
    long next = store.getHead() + 1;
    assertEquals(0, get(next));

    add(next);
    assertEquals(next, get(next));
    assertEquals(next, store.getHead());
    assertEquals(1, store.getTail());

    FsStore store2 = new FsStore(myBase);
    assertEquals(next, store2.getHead());
    assertEquals(1, store2.getTail());
  }

  private void add(long l) throws IOException {
    store.add("" + l);
  }

  private long get(long i) throws IOException {
    String g = store.get(i);
    return g == null ? 0 : Long.parseLong(g);
  }

  @Test
  public void testAddAgain() throws IOException {
    add();
    add();
    add();
  }

  @Test
  public void testTrim() throws IOException {
    add();
    add();
    add();

    assertEquals(1, store.getTail());
    store.trim(1);
    assertEquals(2, store.getTail());
    assertEquals(0, get(1)); // just deleted
    assertEquals(2, get(2)); // beyond deleted

    store.trim(2);
    assertEquals(3, store.getTail());
    assertEquals(0, get(2)); // just deleted
    assertEquals(3, get(3)); // beyond deleted

    store.trim(3);
    assertEquals(3, store.getTail());
    assertEquals(3, get(3)); // cannot delete head
  }

  @Test
  public void testCount() throws Exception {
    for (long i = 0; i < count; i++) {
      add();
    }
  }

  public void count() throws Exception {
    for (long i = 1; i <= count; i++) {
      store.add(id + " " + i);
      System.out.print(submitMarker);
    }
  }

  public boolean verify(long head) throws Exception {
    Set<Long> found = new HashSet<Long>();
    long stop = store.getHead();
    long mine = 1;

    for (long i = head + 1; i <= stop; i++) {
      String event = store.get(i);
      if (event != null) {
        String split[] = event.split(" ");
        if (split != null && id.equals(split[0])) {
          long n = Long.parseLong(split[1]);
          if (!found.add(n)) {
            report("duplicate", n, i);
          }
          if (mine != n) {
            report("ouf of order", n, i);
          }
          mine++;
        }
      } else {
        report("gap", mine, i);
      }
    }
    for (long i = 1; i <= count; i++) {
      if (!found.contains(i)) {
        report("missing", i, -1);
      }
    }

    boolean error = false;
    error |= reportTotal("duplicate");
    error |= reportTotal("out of order");
    error |= reportTotal("missing");
    error |= reportTotal("gap");
    return error;
  }

  private void report(String type, long n, long i) {
    Long cnt = reported.get(type);
    if (cnt == null) {
      System.out.println("First " + type + ": " + n + " pos(" + i + ")");
      cnt = (long) 0;
    }
    reported.put(type, ++cnt);
  }

  private boolean reportTotal(String type) {
    Long cnt = reported.get(type);
    if (cnt != null) {
      System.out.println("Total " + type + "s: " + cnt);
      return true;
    }
    return false;
  }

  /**
   * First, make the junit jar easily available
   *
   * <p>ln -s ~/.m2/repository/junit/junit/4.8.1/junit-4.8.1.jar target
   *
   * <p>To run type:
   *
   * <p>java -cp target/classes:target/test-classes:target/junit-4.8.1.jar \
   * com.googlesource.gerrit.plugins.events.fsstore.FsStoreTest \ [dir [count [store-id]]]
   *
   * <p>Note: if you do not specify <dir>, it will create a directory under /tmp
   *
   * <p>Performance: NFS(Lowlatency,SSDs), 1 worker 1M, 266m ~16ms/event find events|wc -l 12s rm
   * -rf 1m49s du -sh -> 3.9G 1m7s
   *
   * <p>Local(spinning) 1 workers 1M 14.34s ~14us/event find events|wc -l 1.3s rm -rf 42s
   *
   * <p>Multi workers: NFS(LowLatency,LAN,SSDs) 8 hosts count=1000 (each) avg 273s 1000/34s
   *
   * <p>Mixed workers: NFS(WAN) 1 worker (+NFS LAN continuous) count=10, 3m28s
   */
  public static void main(String[] argv) throws Exception {
    if (argv.length > 0) {
      base = Paths.get(argv[0]);
    }
    FsStoreTest t = new FsStoreTest();
    if (argv.length > 1) {
      t.count = Long.parseLong(argv[1]);
    }

    t.submitMarker = ".";
    if (argv.length > 2) {
      t.id = argv[2];
      t.submitMarker += t.id + ".";
    }

    t.setUp();
    long head = t.store.getHead();
    t.count();
    if (t.verify(head)) {
      System.out.println("\nFAIL");
      System.exit(1);
    }
    System.out.println("\nPASS");
  }
}
