/*
 * 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.database.sqlite;

import android.app.ActivityThread;
import android.app.Application;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.KeyValueListParser;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Helper class for accessing
 * {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS global compatibility WAL settings}.
 *
 * <p>The value of {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS} is cached on first access
 * for consistent behavior across all connections opened in the process.
 * @hide
 */
public class SQLiteCompatibilityWalFlags {

    private static final String TAG = "SQLiteCompatibilityWalFlags";

    private static volatile boolean sInitialized;
    private static volatile boolean sFlagsSet;
    private static volatile boolean sCompatibilityWalSupported;
    private static volatile String sWALSyncMode;
    private static volatile long sTruncateSize = -1;
    // This flag is used to avoid recursive initialization due to circular dependency on Settings
    private static volatile boolean sCallingGlobalSettings;

    /**
     * @hide
     */
    @VisibleForTesting
    public static boolean areFlagsSet() {
        initIfNeeded();
        return sFlagsSet;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static boolean isCompatibilityWalSupported() {
        initIfNeeded();
        return sCompatibilityWalSupported;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static String getWALSyncMode() {
        initIfNeeded();
        return sWALSyncMode;
    }

    /**
     * Override {@link com.android.internal.R.integer#db_wal_truncate_size}.
     *
     * @return the value set in the global setting, or -1 if a value is not set.
     *
     * @hide
     */
    @VisibleForTesting
    public static long getTruncateSize() {
        initIfNeeded();
        return sTruncateSize;
    }

    private static void initIfNeeded() {
        if (sInitialized || sCallingGlobalSettings) {
            return;
        }
        ActivityThread activityThread = ActivityThread.currentActivityThread();
        Application app = activityThread == null ? null : activityThread.getApplication();
        String flags = null;
        if (app == null) {
            Log.w(TAG, "Cannot read global setting "
                    + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - "
                    + "Application state not available");
        } else {
            try {
                sCallingGlobalSettings = true;
                flags = Settings.Global.getString(app.getContentResolver(),
                        Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS);
            } finally {
                sCallingGlobalSettings = false;
            }
        }

        init(flags);
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static void init(String flags) {
        if (TextUtils.isEmpty(flags)) {
            sInitialized = true;
            return;
        }
        KeyValueListParser parser = new KeyValueListParser(',');
        try {
            parser.setString(flags);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Setting has invalid format: " + flags, e);
            sInitialized = true;
            return;
        }
        sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported",
                SQLiteGlobal.isCompatibilityWalSupported());
        sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
        sTruncateSize = parser.getInt("truncate_size", -1);
        Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported="
                + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode);
        sFlagsSet = true;
        sInitialized = true;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static void reset() {
        sInitialized = false;
        sFlagsSet = false;
        sCompatibilityWalSupported = false;
        sWALSyncMode = null;
    }
}
