/*
 * Copyright (C) 2016 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 com.android.providers.settings;

import android.os.Bundle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.MemoryIntArray;
import android.util.Slog;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;

import java.io.IOException;

/**
 * This class tracks changes for global/secure/system tables on a
 * per user basis and updates a shared memory region which client
 * processes can read to determine if their local caches are stale,
 */
final class GenerationRegistry {
    private static final String LOG_TAG = "GenerationTracker";

    private static final boolean DEBUG = false;

    private final Object mLock;

    @GuardedBy("mLock")
    private final SparseIntArray mKeyToIndexMap = new SparseIntArray();

    @GuardedBy("mLock")
    private MemoryIntArray mBackingStore;

    public GenerationRegistry(Object lock) {
        mLock = lock;
    }

    public void incrementGeneration(int key) {
        synchronized (mLock) {
            MemoryIntArray backingStore = getBackingStoreLocked();
            if (backingStore != null) {
                try {
                    final int index = getKeyIndexLocked(key, mKeyToIndexMap, backingStore);
                    if (index >= 0) {
                        final int generation = backingStore.get(index) + 1;
                        backingStore.set(index, generation);
                    }
                } catch (IOException e) {
                    Slog.e(LOG_TAG, "Error updating generation id", e);
                    destroyBackingStore();
                }
            }
        }
    }

    public void addGenerationData(Bundle bundle, int key) {
        synchronized (mLock) {
            MemoryIntArray backingStore = getBackingStoreLocked();
            try {
                if (backingStore != null) {
                    final int index = getKeyIndexLocked(key, mKeyToIndexMap, backingStore);
                    if (index >= 0) {
                        bundle.putParcelable(Settings.CALL_METHOD_TRACK_GENERATION_KEY,
                                backingStore);
                        bundle.putInt(Settings.CALL_METHOD_GENERATION_INDEX_KEY, index);
                        bundle.putInt(Settings.CALL_METHOD_GENERATION_KEY,
                                backingStore.get(index));
                        if (DEBUG) {
                            Slog.i(LOG_TAG, "Exported index:" + index + " for key:"
                                    + SettingsProvider.keyToString(key));
                        }
                    }
                }
            } catch (IOException e) {
                Slog.e(LOG_TAG, "Error adding generation data", e);
                destroyBackingStore();
            }
        }
    }

    public void onUserRemoved(int userId) {
        synchronized (mLock) {
            MemoryIntArray backingStore = getBackingStoreLocked();
            if (backingStore != null && mKeyToIndexMap.size() > 0) {
                try {
                    final int secureKey = SettingsProvider.makeKey(
                            SettingsProvider.SETTINGS_TYPE_SECURE, userId);
                    resetSlotForKeyLocked(secureKey, mKeyToIndexMap, backingStore);

                    final int systemKey = SettingsProvider.makeKey(
                            SettingsProvider.SETTINGS_TYPE_SYSTEM, userId);
                    resetSlotForKeyLocked(systemKey, mKeyToIndexMap, backingStore);
                } catch (IOException e) {
                    Slog.e(LOG_TAG, "Error cleaning up for user", e);
                    destroyBackingStore();
                }
            }
        }
    }

    private MemoryIntArray getBackingStoreLocked() {
        if (mBackingStore == null) {
            // One for the global table, two for system and secure tables for a
            // managed profile (managed profile is not included in the max user
            // count), ten for partially deleted users if users are quickly removed,
            // and twice max user count for system and secure.
            final int size = 1 + 2 + 10 + 2 * UserManager.getMaxSupportedUsers();
            try {
                mBackingStore = new MemoryIntArray(size);
            } catch (IOException e) {
                Slog.e(LOG_TAG, "Error creating generation tracker", e);
            }
        }
        return mBackingStore;
    }

    private void destroyBackingStore() {
        if (mBackingStore != null) {
            try {
                mBackingStore.close();
            } catch (IOException e) {
                Slog.e(LOG_TAG, "Cannot close generation memory array", e);
            }
            mBackingStore = null;
        }
    }

    private static void resetSlotForKeyLocked(int key, SparseIntArray keyToIndexMap,
            MemoryIntArray backingStore) throws IOException {
        final int index = keyToIndexMap.get(key, -1);
        if (index >= 0) {
            keyToIndexMap.delete(key);
            backingStore.set(index, 0);
            if (DEBUG) {
                Slog.i(LOG_TAG, "Freed index:" + index + " for key:"
                        + SettingsProvider.keyToString(key));
            }
        }
    }

    private static int getKeyIndexLocked(int key, SparseIntArray keyToIndexMap,
            MemoryIntArray backingStore) throws IOException {
        int index = keyToIndexMap.get(key, -1);
        if (index < 0) {
            index = findNextEmptyIndex(backingStore);
            if (index >= 0) {
                backingStore.set(index, 1);
                keyToIndexMap.append(key, index);
                if (DEBUG) {
                    Slog.i(LOG_TAG, "Allocated index:" + index + " for key:"
                            + SettingsProvider.keyToString(key));
                }
            } else {
                Slog.e(LOG_TAG, "Could not allocate generation index");
            }
        }
        return index;
    }

    private static int findNextEmptyIndex(MemoryIntArray backingStore) throws IOException {
        final int size = backingStore.size();
        for (int i = 0; i < size; i++) {
            if (backingStore.get(i) == 0) {
                return i;
            }
        }
        return -1;
    }
}