/*
 * 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 = "GenerationRegistry";

    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);
                if (DEBUG) {
                    Slog.e(LOG_TAG, "Created backing store " + mBackingStore);
                }
            } catch (IOException e) {
                Slog.e(LOG_TAG, "Error creating generation tracker", e);
            }
        }
        return mBackingStore;
    }

    private void destroyBackingStore() {
        if (mBackingStore != null) {
            try {
                mBackingStore.close();
                if (DEBUG) {
                    Slog.e(LOG_TAG, "Destroyed backing store " + mBackingStore);
                }
            } 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;
    }
}