package uk.ac.ic.wlgitbridge.bridge.db.sqlite;

import org.junit.Before;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import uk.ac.ic.wlgitbridge.bridge.db.ProjectState;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

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

/**
 * Created by winston on 23/08/2016.
 */
public class SqliteDBStoreTest {

    private SqliteDBStore dbStore;

    @Before
    public void setup() throws IOException {
        TemporaryFolder tmpFolder = new TemporaryFolder();
        tmpFolder.create();
        dbStore = new SqliteDBStore(tmpFolder.newFile("dbStore.db"));
    }

    @Test
    public void testGetNumProjects() {
        assertEquals(0, dbStore.getNumProjects());
        dbStore.setLatestVersionForProject("asdf", 1);
        assertEquals(1, dbStore.getNumProjects());
        dbStore.setLatestVersionForProject("asdf1", 2);
        assertEquals(2, dbStore.getNumProjects());
        dbStore.setLatestVersionForProject("asdf1", 3);
        assertEquals(2, dbStore.getNumProjects());
    }

    @Test
    public void swapTableStartsOutEmpty() {
        assertNull(dbStore.getOldestUnswappedProject());
    }

    @Test
    public void testGetOldestUnswappedProject() {
        dbStore.setLatestVersionForProject("older", 3);
        dbStore.setLastAccessedTime(
                "older",
                Timestamp.valueOf(
                        LocalDateTime.now().minus(5, ChronoUnit.SECONDS)
                )
        );
        dbStore.setLatestVersionForProject("asdf", 1);
        dbStore.setLastAccessedTime(
                "asdf",
                Timestamp.valueOf(
                        LocalDateTime.now().minus(1, ChronoUnit.SECONDS)
                )
        );
        assertEquals("older", dbStore.getOldestUnswappedProject());
        dbStore.setLastAccessedTime(
                "older",
                Timestamp.valueOf(
                        LocalDateTime.now()
                )
        );
        assertEquals("asdf", dbStore.getOldestUnswappedProject());
    }

    @Test
    public void noOldestProjectIfAllEvicted() {
        dbStore.setLatestVersionForProject("older", 3);
        dbStore.setLastAccessedTime("older", null);
        assertNull(dbStore.getOldestUnswappedProject());
    }

    @Test
    public void nullLastAccessedTimesDoNotCount() {
        dbStore.setLatestVersionForProject("older", 2);
        dbStore.setLastAccessedTime(
                "older",
                Timestamp.valueOf(
                        LocalDateTime.now().minus(5, ChronoUnit.SECONDS)
                )
        );
        dbStore.setLatestVersionForProject("newer", 3);
        dbStore.setLastAccessedTime(
                "newer",
                Timestamp.valueOf(
                        LocalDateTime.now()
                )
        );
        assertEquals("older", dbStore.getOldestUnswappedProject());
        dbStore.setLastAccessedTime("older", null);
        assertEquals("newer", dbStore.getOldestUnswappedProject());
    }

    @Test
    public void missingProjectLastAccessedTimeCanBeSet() {
        dbStore.setLatestVersionForProject("asdf", 1);
        dbStore.setLastAccessedTime(
                "asdf",
                Timestamp.valueOf(LocalDateTime.now())
        );
        assertEquals("asdf", dbStore.getOldestUnswappedProject());
    }

    @Test
    public void testGetNumUnswappedProjects() {
        dbStore.setLatestVersionForProject("asdf", 1);
        dbStore.setLastAccessedTime(
                "asdf",
                Timestamp.valueOf(LocalDateTime.now())
        );
        assertEquals(1, dbStore.getNumUnswappedProjects());
        dbStore.setLastAccessedTime(
                "asdf",
                null
        );
        assertEquals(0, dbStore.getNumUnswappedProjects());
    }

    @Test
    public void projectStateIsNotPresentIfNotInDBAtAll() {
        assertEquals(
                ProjectState.NOT_PRESENT,
                dbStore.getProjectState("asdf")
        );
    }

    @Test
    public void projectStateIsPresentIfProjectHasLastAccessed() {
        dbStore.setLatestVersionForProject("asdf", 1);
        dbStore.setLastAccessedTime(
                "asdf",
                Timestamp.valueOf(LocalDateTime.now())
        );
        assertEquals(ProjectState.PRESENT, dbStore.getProjectState("asdf"));
    }

    @Test
    public void projectStateIsSwappedIfLastAccessedIsNull() {
        dbStore.setLatestVersionForProject("asdf", 1);
        dbStore.setLastAccessedTime("asdf", null);
        assertEquals(ProjectState.SWAPPED, dbStore.getProjectState("asdf"));
    }

}
@@ -2150,32 +2150,518 @@
 ject());%0A    %7D%0A%0A
+    @Test%0A    public void swapAndRestore() %7B%0A      String projectName = %22something%22;%0A      String compression = %22bzip2%22;%0A      dbStore.setLatestVersionForProject(projectName, 42);%0A      dbStore.swap(projectName, compression);%0A      assertNull(dbStore.getOldestUnswappedProject());%0A      assertEquals(dbStore.getSwapCompression(projectName), compression);%0A      // and restore%0A      dbStore.restore(projectName);%0A      assertEquals(dbStore.getSwapCompression(projectName), null);%0A    %7D%0A%0A
     @Test%0A    pu
@@ -2775,34 +2775,19 @@
 bStore.s
-etLastAccessedTime
+wap
 (%22older%22
@@ -2780,36 +2780,39 @@
 e.swap(%22older%22, 
-null
+%22bzip2%22
 );%0A        asser
@@ -3490,34 +3490,19 @@
 bStore.s
-etLastAccessedTime
+wap
 (%22older%22
@@ -3503,20 +3503,23 @@
 older%22, 
-null
+%22bzip2%22
 );%0A     
@@ -4230,34 +4230,19 @@
 bStore.s
-etLastAccessedTime
+wap
 (%0A      
@@ -4275,20 +4275,23 @@
         
-null
+%22bzip2%22
 %0A       
@@ -5046,34 +5046,19 @@
 bStore.s
-etLastAccessedTime
+wap
 (%22asdf%22,
@@ -5058,20 +5058,23 @@
 %22asdf%22, 
-null
+%22bzip2%22
 );%0A     
@@ -5153,8 +5153,9 @@
     %7D%0A%0A%7D
+%0A

Update SqliteDBStoreTest with swap/compression