/*
 * 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.server.pm;

import android.os.SystemProperties;

import dalvik.system.DexFile;

/**
 * Manage (retrieve) mappings from compilation reason to compilation filter.
 */
public class PackageManagerServiceCompilerMapping {
    // Names for compilation reasons.
    public static final String REASON_STRINGS[] = {
            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared"
    };

    static final int REASON_SHARED_INDEX = 6;

    // Static block to ensure the strings array is of the right length.
    static {
        if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
            throw new IllegalStateException("REASON_STRINGS not correct");
        }
        if (!"shared".equals(REASON_STRINGS[REASON_SHARED_INDEX])) {
            throw new IllegalStateException("REASON_STRINGS not correct because of shared index");
        }
    }

    private static String getSystemPropertyName(int reason) {
        if (reason < 0 || reason >= REASON_STRINGS.length) {
            throw new IllegalArgumentException("reason " + reason + " invalid");
        }

        return "pm.dexopt." + REASON_STRINGS[reason];
    }

    // Load the property for the given reason and check for validity. This will throw an
    // exception in case the reason or value are invalid.
    private static String getAndCheckValidity(int reason) {
        String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
        if (sysPropValue == null || sysPropValue.isEmpty() ||
                !DexFile.isValidCompilerFilter(sysPropValue)) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        } else if (!isFilterAllowedForReason(reason, sysPropValue)) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        }

        return sysPropValue;
    }

    private static boolean isFilterAllowedForReason(int reason, String filter) {
        return reason != REASON_SHARED_INDEX || !DexFile.isProfileGuidedCompilerFilter(filter);
    }

    // Check that the properties are set and valid.
    // Note: this is done in a separate method so this class can be statically initialized.
    static void checkProperties() {
        // We're gonna check all properties and collect the exceptions, so we can give a general
        // overview. Store the exceptions here.
        RuntimeException toThrow = null;

        for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
            try {
                // Check that the system property name is legal.
                String sysPropName = getSystemPropertyName(reason);
                if (sysPropName == null || sysPropName.isEmpty()) {
                    throw new IllegalStateException("Reason system property name \"" +
                            sysPropName +"\" for reason " + REASON_STRINGS[reason]);
                }

                // Check validity, ignore result.
                getAndCheckValidity(reason);
            } catch (Exception exc) {
                if (toThrow == null) {
                    toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
                }
                toThrow.addSuppressed(exc);
            }
        }

        if (toThrow != null) {
            throw toThrow;
        }
    }

    public static String getCompilerFilterForReason(int reason) {
        return getAndCheckValidity(reason);
    }

    /**
     * Return the default compiler filter for compilation.
     *
     * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
     * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
     */
    public static String getDefaultCompilerFilter() {
        String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
        if (value == null || value.isEmpty()) {
            return "speed";
        }

        if (!DexFile.isValidCompilerFilter(value) ||
                DexFile.isProfileGuidedCompilerFilter(value)) {
            return "speed";
        }

        return value;
    }

    public static String getReasonName(int reason) {
        if (reason == PackageManagerService.REASON_UNKNOWN) {
            return "unknown";
        }
        if (reason < 0 || reason >= REASON_STRINGS.length) {
            throw new IllegalArgumentException("reason " + reason + " invalid");
        }
        return REASON_STRINGS[reason];
    }
}
