package org.commcare.models.database;

import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.util.Log;

import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;

import org.commcare.modern.database.DatabaseHelper;

import java.io.File;

public class DbUtil {
    private static final String TAG = DbUtil.class.getSimpleName();
    public final static String orphanFileTableName = "OrphanedFiles";

    /**
     * Provides a hook for Sqllite databases to be able to try to migrate themselves in place
     * from the writabledatabase method. Required due to SqlCipher making it incredibly difficult
     * and obnoxious to determine when your databases need an upgrade, so we'll just try to run
     * one any time the method would have crashed anyway.
     *
     * Will crash if this update doesn't work, so no return is needed
     */
    public static void trySqlCipherDbUpdate(String key, Context context, String dbName) {
        //There's no clear way how to tell whether this call is the invalid db version
        //because SqlLite didn't actually provide that info (thanks!), but we can
        //test manually

        //Set up the hook to fire the right pragma ops
        SQLiteDatabaseHook updateHook = new SQLiteDatabaseHook() {

            @Override
            public void preKey(SQLiteDatabase database) {
            }

            @Override
            public void postKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA cipher_migrate;");
            }
        };

        //go find the db path because the helper hides this (thanks android)
        File dbPath = context.getDatabasePath(dbName);

        SQLiteDatabase oldDb = SQLiteDatabase.openOrCreateDatabase(dbPath, key, null, updateHook);

        //if we didn't get here, we didn't crash (what a great way to be testing our db version, right?)
        oldDb.close();
    }

    public static void createNumbersTable(SQLiteDatabase db) {
        //Virtual Table
        String dropStatement = "DROP TABLE IF EXISTS integers;";
        db.execSQL(dropStatement);
        String createStatement = "CREATE TABLE integers (i INTEGER);";
        db.execSQL(createStatement);

        for (long i = 0; i < 10; ++i) {
            db.execSQL("INSERT INTO integers VALUES (" + i + ");");
        }
    }

    public static void explainSql(SQLiteDatabase handle, String sql, String[] args) {
        Cursor explain = handle.rawQuery("EXPLAIN QUERY PLAN " + sql, args);
        Log.d(TAG, "SQL: " + sql);
        DatabaseUtils.dumpCursor(explain);
        explain.close();
    }

    /**
     * Table of files scheduled for deletion. Entries added when file-based
     * database transactions fail or when file-backed entries are removed.
     */
    public static void createOrphanedFileTable(SQLiteDatabase db) {
        String createStatement = "CREATE TABLE IF NOT EXISTS " + orphanFileTableName + " (" + DatabaseHelper.FILE_COL + ");";
        db.execSQL(createStatement);
    }

    /**
     * Build and return SQL command to add a column to a table
     */
    public static String addColumnToTable(String tableName, String columnName, String dataType) {
        return "ALTER TABLE " + tableName + " ADD " +
                AndroidTableBuilder.scrubName(columnName) + " " + dataType;
    }

}

@@ -2926,32 +2926,48 @@
 reateStatement =
+%0A               
  %22CREATE TABLE I
@@ -2984,30 +2984,78 @@
 TS %22
- + orphanFileTableName
+%0A                        + orphanFileTableName%0A                       
  + %22
@@ -3449,11 +3449,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

remove linebreak