/*
 * Copyright (C) 2007 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.database.sqlite;

import android.annotation.TestApi;
import android.os.Build;
import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Printer;

import java.util.ArrayList;

/**
 * Provides debugging info about all SQLite databases running in the current process.
 *
 * {@hide}
 */
@TestApi
public final class SQLiteDebug {
    private static native void nativeGetPagerStats(PagerStats stats);

    /**
     * Inner class to avoid getting the value frozen in zygote.
     *
     * {@hide}
     */
    public static final class NoPreloadHolder {
        /**
         * Controls the printing of informational SQL log messages.
         *
         * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
         */
        public static final boolean DEBUG_SQL_LOG =
                Log.isLoggable("SQLiteLog", Log.VERBOSE);

        /**
         * Controls the printing of SQL statements as they are executed.
         *
         * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
         */
        public static final boolean DEBUG_SQL_STATEMENTS =
                Log.isLoggable("SQLiteStatements", Log.VERBOSE);

        /**
         * Controls the printing of wall-clock time taken to execute SQL statements
         * as they are executed.
         *
         * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
         */
        public static final boolean DEBUG_SQL_TIME =
                Log.isLoggable("SQLiteTime", Log.VERBOSE);


        /**
         * True to enable database performance testing instrumentation.
         */
        public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;

        private static final String SLOW_QUERY_THRESHOLD_PROP = "db.log.slow_query_threshold";

        private static final String SLOW_QUERY_THRESHOLD_UID_PROP =
                SLOW_QUERY_THRESHOLD_PROP + "." + Process.myUid();

        /**
         * Whether to add detailed information to slow query log.
         */
        public static final boolean DEBUG_LOG_DETAILED = Build.IS_DEBUGGABLE
                && SystemProperties.getBoolean("db.log.detailed", false);
    }

    private SQLiteDebug() {
    }

    /**
     * Determines whether a query should be logged.
     *
     * Reads the "db.log.slow_query_threshold" system property, which can be changed
     * by the user at any time.  If the value is zero, then all queries will
     * be considered slow.  If the value does not exist or is negative, then no queries will
     * be considered slow.
     *
     * To enable it for a specific UID, "db.log.slow_query_threshold.UID" could also be used.
     *
     * This value can be changed dynamically while the system is running.
     * For example, "adb shell setprop db.log.slow_query_threshold 200" will
     * log all queries that take 200ms or longer to run.
     * @hide
     */
    public static boolean shouldLogSlowQuery(long elapsedTimeMillis) {
        final int slowQueryMillis = Math.min(
                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_PROP,
                        Integer.MAX_VALUE),
                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_UID_PROP,
                        Integer.MAX_VALUE));
        return elapsedTimeMillis >= slowQueryMillis;
    }

    /**
     * Contains statistics about the active pagers in the current process.
     *
     * @see #nativeGetPagerStats(PagerStats)
     */
    public static class PagerStats {
        /** the current amount of memory checked out by sqlite using sqlite3_malloc().
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
         */
        public int memoryUsed;

        /** the number of bytes of page cache allocation which could not be sattisfied by the
         * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc().
         * The returned value includes allocations that overflowed because they where too large
         * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations
         * that overflowed because no space was left in the page cache.
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
         */
        public int pageCacheOverflow;

        /** records the largest memory allocation request handed to sqlite3.
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
         */
        public int largestMemAlloc;

        /** a list of {@link DbStats} - one for each main database opened by the applications
         * running on the android device
         */
        public ArrayList<DbStats> dbStats;
    }

    /**
     * contains statistics about a database
     */
    public static class DbStats {
        /** name of the database */
        public String dbName;

        /** the page size for the database */
        public long pageSize;

        /** the database size */
        public long dbSize;

        /**
         * Number of lookaside slots: http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
        public int lookaside;

        /** statement cache stats: hits/misses/cachesize */
        public String cache;

        public DbStats(String dbName, long pageCount, long pageSize, int lookaside,
            int hits, int misses, int cachesize) {
            this.dbName = dbName;
            this.pageSize = pageSize / 1024;
            dbSize = (pageCount * pageSize) / 1024;
            this.lookaside = lookaside;
            this.cache = hits + "/" + misses + "/" + cachesize;
        }
    }

    /**
     * return all pager and database stats for the current process.
     * @return {@link PagerStats}
     */
    public static PagerStats getDatabaseInfo() {
        PagerStats stats = new PagerStats();
        nativeGetPagerStats(stats);
        stats.dbStats = SQLiteDatabase.getDbStats();
        return stats;
    }

    /**
     * Dumps detailed information about all databases used by the process.
     * @param printer The printer for dumping database state.
     * @param args Command-line arguments supplied to dumpsys dbinfo
     */
    public static void dump(Printer printer, String[] args) {
        dump(printer, args, false);
    }

    /** @hide */
    public static void dump(Printer printer, String[] args, boolean isSystem) {
        boolean verbose = false;
        for (String arg : args) {
            if (arg.equals("-v")) {
                verbose = true;
            }
        }

        SQLiteDatabase.dumpAll(printer, verbose, isSystem);
    }
}
