/*
 * 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 android.arch.persistence.room.integration.testapp.test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.IsCollectionContaining.hasItem;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.integration.testapp.TestDatabase;
import android.arch.persistence.room.integration.testapp.vo.User;
import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;

@RunWith(AndroidJUnit4.class)
public class DatabaseCallbackTest {

    @Test
    @MediumTest
    public void createAndOpen() {
        Context context = InstrumentationRegistry.getTargetContext();
        TestDatabaseCallback callback1 = new TestDatabaseCallback();
        TestDatabase db1 = Room.databaseBuilder(context, TestDatabase.class, "test")
                .addCallback(callback1)
                .build();
        assertFalse(callback1.mCreated);
        assertFalse(callback1.mOpened);
        User user1 = TestUtil.createUser(3);
        user1.setName("george");
        db1.getUserDao().insert(user1);
        assertTrue(callback1.mCreated);
        assertTrue(callback1.mOpened);
        TestDatabaseCallback callback2 = new TestDatabaseCallback();
        TestDatabase db2 = Room.databaseBuilder(context, TestDatabase.class, "test")
                .addCallback(callback2)
                .build();
        assertFalse(callback2.mCreated);
        assertFalse(callback2.mOpened);
        User user2 = db2.getUserDao().load(3);
        assertThat(user2.getName(), is("george"));
        assertFalse(callback2.mCreated); // Not called; already created by db1
        assertTrue(callback2.mOpened);
    }

    @Test
    @SmallTest
    public void writeOnCreate() {
        Context context = InstrumentationRegistry.getTargetContext();
        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class)
                .addCallback(new RoomDatabase.Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        Cursor cursor = null;
                        try {
                            cursor = db.query(
                                    "SELECT name FROM sqlite_master WHERE type = 'table'");
                            ArrayList<String> names = new ArrayList<>();
                            while (cursor.moveToNext()) {
                                names.add(cursor.getString(0));
                            }
                            assertThat(names, hasItem("User"));
                        } finally {
                            if (cursor != null) {
                                cursor.close();
                            }
                        }
                    }
                })
                .build();
        List<Integer> ids = db.getUserDao().loadIds();
        assertThat(ids, is(empty()));
    }

    public static class TestDatabaseCallback extends RoomDatabase.Callback {

        boolean mCreated;
        boolean mOpened;

        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            mCreated = true;
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            mOpened = true;
        }
    }
}

@@ -1967,16 +1967,87 @@
 se db1 =
+ null;%0A        TestDatabase db2 = null;%0A        try %7B%0A            db1 =
  Room.da
@@ -2105,32 +2105,36 @@
                 
+   
+ 
 .addCallback(cal
@@ -2149,32 +2149,36 @@
                 
+    
 .build();%0A      
@@ -2171,32 +2171,36 @@
 uild();%0A        
+ 
+   
 assertFalse(call
@@ -2216,32 +2216,36 @@
 eated);%0A        
+   
+ 
 assertFalse(call
@@ -2252,32 +2252,36 @@
 back1.mOpened);%0A
+    
         User use
@@ -2317,16 +2317,20 @@
         
+ 
+   
 user1.se
@@ -2354,16 +2354,20 @@
         
+   
+ 
 db1.getU
@@ -2390,16 +2390,20 @@
 user1);%0A
+    
         
@@ -2434,32 +2434,36 @@
 eated);%0A        
+  
+  
 assertTrue(callb
@@ -2469,32 +2469,36 @@
 back1.mOpened);%0A
+    
         TestData
@@ -2554,36 +2554,27 @@
 ();%0A        
-TestDatabase
+   
  db2 = Room.
@@ -2634,32 +2634,36 @@
                 
+    
 .addCallback(cal
@@ -2678,32 +2678,36 @@
                 
+    
 .build();%0A      
@@ -2700,32 +2700,36 @@
 uild();%0A        
+ 
+   
 assertFalse(call
@@ -2745,32 +2745,36 @@
 eated);%0A        
+   
+ 
 assertFalse(call
@@ -2781,32 +2781,36 @@
 back2.mOpened);%0A
+    
         User use
@@ -2840,32 +2840,36 @@
 oad(3);%0A        
+ 
+   
 assertThat(user2
@@ -2891,24 +2891,28 @@
 %22george%22));%0A
+    
         asse
@@ -2978,32 +2978,36 @@
  by db1%0A        
+    
 assertTrue(callb
@@ -3017,24 +3017,258 @@
 2.mOpened);%0A
+        %7D finally %7B%0A            if (db1 != null) %7B%0A                db1.close();%0A            %7D%0A            if (db2 != null) %7B%0A                db2.close();%0A            %7D%0A            assertTrue(context.deleteDatabase(%22test%22));%0A        %7D%0A
     %7D%0A%0A    @

Fix DatabaseCallbackTest.createAndOpen am: 17924f721e