// Copyright 2020 Google LLC
//
// 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
//
//     https://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.google.graphgeckos.dashboard.storage;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.cloud.Timestamp;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class DatastoreRepositoryTests {
  private final LocalServiceTestHelper helper =
      new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

  private BuildInfo getDummyEntity(String commitHash) {
    return new BuildInfo(new ParsedGitData(commitHash, Timestamp.now(), "test"));
  }

  private ParsedBuildbotData getDummyUpdate(String commitHash) {
    return new ParsedBuildbotData(commitHash, "tester", new ArrayList<>(), BuilderStatus.PASSED);
  }

  @Before
  public void setUp() {
    helper.setUp();
  }

  @After
  public void tearDown() {
    helper.tearDown();
  }

  @Test
  public void testValidRequestSequenceValidData() {
    DatastoreRepository storage = new DatastoreRepository();
    
    Assert.assertTrue(storage.createRevisionEntry(getDummyEntity("1")));
    Assert.assertEquals(getDummyEntity("1"), storage.getRevisionEntry("1"));
    Assert.assertTrue(storage.updateRevisionEntry(getDummyUpdate("1")));

    BuildInfo dummy = getDummyEntity("1");
    dummy.addBuilder(new Builder(getDummyUpdate("1")));
    Assert.assertEquals(dummy, storage.getRevisionEntry("1"));

    Assert.assertTrue(storage.deleteRevisionEntry("1"));
    Assert.assertEquals(null, storage.getRevisionEntry("1"));
  }

  @Test
  public void testValidRequestSequenceNullData() {
    DatastoreRepository storage = new DatastoreRepository();

    Assert.assertFalse(storage.createRevisionEntry(null));
    Assert.assertFalse(storage.getRevisionEntry(null));
    Assert.assertFalse(storage.updateRevisionEntry(null));
    Assert.assertFalse(storage.deleteRevisionEntry(null));
  }

  @Test
  public void testValidRequestSequenceInvalidData() {
    DatastoreRepository storage = new DatastoreRepository(initialCleanupDelayDefault,
                                                          cleanupPeriodDefault,
                                                          cleanupPeriodTimeunitDefault,
                                                          ttlDefault,
                                                          ttlTimeUnitDefault);
    Assert.assertTrue(storage.createRevisionEntry(getDummyEntity("1")));
    Assert.assertFalse(storage.createRevisionEntry(getDummyEntity("1")));

    Assert.assertFalse(storage.updateRevisionEntry(getDummyUpdate("2")));

    Assert.assertEquals(null, storage.getRevisionEntry("2"));

    Assert.assertTrue(storage.deleteRevisionEntry("2"));
  }

  @Test
  public void testInvalidRequestSequenceValidData() {

  }

  @Test
  public void testParallelValidRequests() {

  }

  @Test
  public void testGetLastRevisions() {

  }
}

@@ -943,53 +943,16 @@
 til.
-Calendar;%0Aimport java.util.concurrent.TimeUni
+ArrayLis
 t;%0Ai
@@ -1637,37 +1637,32 @@
 public void test
-Valid
 RequestSequenceV
@@ -1740,16 +1740,43 @@
 );%0A    %0A
+    // Test valid addition%0A
     Asse
@@ -1908,32 +1908,58 @@
 sionEntry(%221%22));
+%0A%0A    // Test valid update
 %0A    Assert.asse
@@ -2012,25 +2012,24 @@
 ate(%221%22)));%0A
-%0A
     BuildInf
@@ -2175,24 +2175,51 @@
 try(%221%22));%0A%0A
+    // Test valid deletion%0A
     Assert.a
@@ -2356,36 +2356,24 @@
 oid test
-Valid
 Request
-Sequence
+s
 NullData
@@ -2703,21 +2703,16 @@
 oid test
-Valid
 RequestS
@@ -2796,352 +2796,41 @@
 ory(
-initialCleanupDelayDefault,%0A                                                          cleanupPeriodDefault,%0A                                                          cleanupPeriodTimeunitDefault,%0A                                                          ttlDefault,%0A                                                          ttlTimeUnitDefault);
+);%0A%0A    // Test adding same entry
 %0A   
@@ -2970,24 +2970,62 @@
 ty(%221%22)));%0A%0A
+    // Test updating inexistent entry%0A
     Assert.a
@@ -3083,24 +3083,61 @@
 te(%222%22)));%0A%0A
+    // Test getting inexistent entry%0A
     Assert.a
@@ -3183,24 +3183,62 @@
 try(%222%22));%0A%0A
+    // Test deleting inexistent entry%0A
     Assert.a
@@ -3317,102 +3317,804 @@
 test
-InvalidRequestSequenceValidData() %7B%0A%0A  %7D%0A%0A  @Test%0A  public void testParallelValidRequests() %7B%0A
+ParallelBurstRequests() %7B%0A    DatastoreRepository storage = new DatastoreRepository();%0A%0A    Assert.assertTrue(storage.createRevisionEntry(getDummyEntity(%221%22)));%0A    Assert.assertTrue(storage.createRevisionEntry(getDummyEntity(%222%22)));%0A%0A    Runnable burstRequest = () -%3E %7B%0A      for (int i = 0; i %3C 10; ++i) %7B%0A        Assert.assertTrue(storage.updateRevisionEntry(getDummyUpdate(%221%22)));%0A        Assert.assertTrue(storage.updateRevisionEntry(getDummyUpdate(%222%22)));%0A      %7D%0A    %7D%0A%0A    Thread thread1 = new Thread(burstRequest);%0A    Thread thread2 = new Thread(burstRequest);%0A    Thread thread3 = new Thread(burstRequest);%0A%0A    thread1.start();%0A    thread2.start();%0A    thread3.start();%0A%0A    Assert.assertTrue(storage.deleteRevisionEntry(%221%22));%0A    Assert.assertTrue(storage.deleteRevisionEntry(%222%22));
 %0A  %7D

add parallel tests