/*
 * Copyright (C) 2019 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.server.utils;

import android.annotation.Nullable;
import android.provider.DeviceConfig;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.RescueParty;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Utilities for interacting with the {@link android.provider.DeviceConfig}.
 *
 * @hide
 */
public final class FlagNamespaceUtils {
    /**
     * Special String used for communicating through {@link #RESET_PLATFORM_PACKAGE_FLAG} that
     * Settings were reset by the RescueParty, no actual namespace with this name exists in
     * {@link DeviceConfig}.
     */
    public static final String NAMESPACE_NO_PACKAGE = "no_package";

    /**
     * Name of the special namespace in DeviceConfig table used for communicating resets.
     */
    @VisibleForTesting
    public static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
    /**
     * Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY}, holding all known {@link
     * DeviceConfig} namespaces, as a {@link #DELIMITER} separated String. It's updated after the
     * first time flags are written to the new namespace in the {@link DeviceConfig}.
     */
    @VisibleForTesting
    public static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
    /**
     * Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY} with integer counter
     * suffix added to it, holding {@link DeviceConfig} namespace value whose flags were recently
     * reset by the {@link RescueParty}. It's updated by {@link RescueParty} every time given
     * namespace flags are reset.
     */
    @VisibleForTesting
    public static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
    private static final String DELIMITER = ":";
    /**
     * Maximum value of the counter used in combination with {@link #RESET_PLATFORM_PACKAGE_FLAG}
     * when communicating recently reset by the RescueParty namespace values.
     */
    private static final int MAX_COUNTER_VALUE = 50;

    private static int sKnownResetNamespacesFlagCounter = -1;

    /**
     * Sets the union of {@link #RESET_PLATFORM_PACKAGE_FLAG} with
     * {@link #sKnownResetNamespacesFlagCounter} in the DeviceConfig for each namespace
     * in the consumed namespacesList. These flags are used for communicating the namespaces
     * (aka platform packages) whose flags in {@link DeviceConfig} were just reset
     * by the RescueParty.
     */
    public static void addToKnownResetNamespaces(@Nullable List<String> namespacesList) {
        if (namespacesList == null) {
            return;
        }
        for (String namespace : namespacesList) {
            addToKnownResetNamespaces(namespace);
        }
    }

    /**
     * Sets the union of {@link #RESET_PLATFORM_PACKAGE_FLAG} with
     * {@link #sKnownResetNamespacesFlagCounter} in the DeviceConfig for the consumed namespace.
     * This flag is used for communicating the namespace (aka platform package) whose flags
     * in {@link DeviceConfig} were just reset by the RescueParty.
     */
    public static void addToKnownResetNamespaces(String namespace) {
        int nextFlagCounter = incrementAndRetrieveResetNamespacesFlagCounter();
        DeviceConfig.setProperty(NAMESPACE_RESCUE_PARTY,
                RESET_PLATFORM_PACKAGE_FLAG + nextFlagCounter,
                namespace, /*makeDefault=*/ true);
    }

    /**
     * Reset all namespaces in DeviceConfig with consumed resetMode.
     */
    public static void resetDeviceConfig(int resetMode) {
        resetDeviceConfig(resetMode, getAllKnownDeviceConfigNamespacesList());
    }

    /**
     * Reset all consumed namespaces in DeviceConfig with consumed resetMode.
     */
    public static void resetDeviceConfig(int resetMode, List<String> namespacesList) {
        for (String namespace : namespacesList) {
            DeviceConfig.resetToDefaults(resetMode, namespace);
        }
        addToKnownResetNamespaces(namespacesList);
    }

    /**
     * Resets known reset namespaces flag counter for tests only.
     */
    @VisibleForTesting
    public static void resetKnownResetNamespacesFlagCounterForTest() {
        sKnownResetNamespacesFlagCounter = -1;
    }

    /**
     * Returns a list of all known DeviceConfig namespaces, except for the special {@link
     * #NAMESPACE_RESCUE_PARTY}
     */
    private static List<String> getAllKnownDeviceConfigNamespacesList() {
        String namespacesStr = DeviceConfig.getProperty(NAMESPACE_RESCUE_PARTY,
                ALL_KNOWN_NAMESPACES_FLAG);
        List<String> namespacesList = toStringList(namespacesStr);
        namespacesList.remove(NAMESPACE_RESCUE_PARTY);
        return namespacesList;
    }

    private static List<String> toStringList(String serialized) {
        if (serialized == null || serialized.length() == 0) {
            return new ArrayList<>();
        }
        return Arrays.asList(serialized.split(DELIMITER));
    }

    private static int incrementAndRetrieveResetNamespacesFlagCounter() {
        sKnownResetNamespacesFlagCounter++;
        if (sKnownResetNamespacesFlagCounter == MAX_COUNTER_VALUE) {
            sKnownResetNamespacesFlagCounter = 0;
        }
        return sKnownResetNamespacesFlagCounter;
    }
}
