package org.wikipedia.database;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import org.wikipedia.WikipediaApp;

public class AppContentProvider extends ContentProvider {
    @Override public boolean onCreate() {
        @SuppressWarnings("UnnecessaryLocalVariable") final boolean loaded = true;
        return loaded;
    }

    @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection,
                                            @Nullable String selection,
                                            @Nullable String[] selectionArgs,
                                            @Nullable String sortOrder) {
        AppContentProviderEndpoint endpoint = AppContentProviderEndpoint.of(uri);

        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(endpoint.tables());

        SQLiteDatabase db = readableDatabase();
        final String groupBy = null;
        final String having = null;
        Cursor cursor = builder.query(db, projection == null ? endpoint.projection() : projection,
                selection, selectionArgs, groupBy, having, sortOrder);

        if (cursor != null) {
            cursor.setNotificationUri(getContentResolver(), uri);
        }
        return cursor;
    }

    @Nullable @Override public String getType(@NonNull Uri uri) {
        AppContentProviderEndpoint endpoint = AppContentProviderEndpoint.of(uri);
        return endpoint.type();
    }

    @Nullable @Override public Uri insert(@NonNull Uri uri, ContentValues values) {
        AppContentProviderEndpoint endpoint = AppContentProviderEndpoint.of(uri);

        SQLiteDatabase db = writableDatabase();
        final String nullColumnHack = null;
        db.replaceOrThrow(endpoint.tables(), nullColumnHack, values);

        notifyChange(uri);

        Uri itemUri = endpoint.itemUri(values);
        if (itemUri != null) {
            notifyChange(itemUri);
        }
        return itemUri;
    }

    @Override public int delete(@NonNull Uri uri, @Nullable String selection,
                                @Nullable String[] selectionArgs) {
        AppContentProviderEndpoint endpoint = AppContentProviderEndpoint.of(uri);

        SQLiteDatabase db = writableDatabase();
        int rows = db.delete(endpoint.tables(), selection, selectionArgs);

        notifyChange(uri);
        return rows;
    }

    @Override public int update(@NonNull Uri uri, @Nullable ContentValues values,
                                @Nullable String selection, @Nullable String[] selectionArgs) {
        AppContentProviderEndpoint endpoint = AppContentProviderEndpoint.of(uri);

        SQLiteDatabase db = writableDatabase();
        int rows = db.update(endpoint.tables(), values, selection, selectionArgs);

        notifyChange(uri);
        return rows;
    }

    private void notifyChange(@NonNull Uri uri) {
        if (getContentResolver() != null) {
            getContentResolver().notifyChange(uri, null);
        }
    }

    @Nullable private ContentResolver getContentResolver() {
        return getContext() == null ? null : getContext().getContentResolver();
    }

    private SQLiteDatabase readableDatabase() {
        return WikipediaApp.getInstance().getDatabase().getReadableDatabase();
    }

    private SQLiteDatabase writableDatabase() {
        return WikipediaApp.getInstance().getDatabase().getWritableDatabase();
    }
}
@@ -420,16 +420,75 @@
 ediaApp;
+%0Aimport org.wikipedia.util.log.L;%0A%0Aimport java.util.Arrays;
 %0A%0Apublic
@@ -539,16 +539,63 @@
 vider %7B%0A
+    private static final boolean LOG = false;%0A%0A
     @Ove
@@ -1364,32 +1364,296 @@
  having = null;%0A
+%0A        if (LOG) %7B%0A            L.d(%22selectionArgs=%22 + Arrays.toString(selectionArgs));%0A            String sql = builder.buildQuery(projection, %22(%22 + selection + %22)%22, groupBy, having,%0A                    sortOrder, null);%0A            L.d(%22sql=%22 + sql);%0A        %7D%0A%0A
         Cursor c
@@ -1829,32 +1829,181 @@
 rsor != null) %7B%0A
+            if (LOG) %7B%0A                L.d(%22count=%22 + cursor.getCount() + %22 columnNames=%22 + Arrays.toString(cursor.getColumnNames()));%0A            %7D%0A
             curs
@@ -4233,8 +4233,9 @@
 %0A    %7D%0A%7D
+%0A

Add debug logging to ContentProvider queries