/*
 * Copyright (C) 2020 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.parsing.pkg;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.os.incremental.IncrementalManager;

import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.pm.parsing.PackageParserException;
import com.android.internal.pm.parsing.pkg.AndroidPackageHidden;
import com.android.internal.pm.parsing.pkg.PackageImpl;
import com.android.internal.pm.pkg.component.ParsedActivity;
import com.android.internal.pm.pkg.component.ParsedInstrumentation;
import com.android.internal.pm.pkg.component.ParsedProvider;
import com.android.internal.pm.pkg.component.ParsedService;
import com.android.internal.pm.pkg.parsing.ParsingPackageHidden;
import com.android.internal.util.ArrayUtils;
import com.android.server.SystemConfig;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/** @hide */
public class AndroidPackageUtils {

    private AndroidPackageUtils() {
    }

    public static List<String> getAllCodePathsExcludingResourceOnly(
            AndroidPackage aPkg) {
        PackageImpl pkg = (PackageImpl) aPkg;
        ArrayList<String> paths = new ArrayList<>();
        if (pkg.isDeclaredHavingCode()) {
            paths.add(pkg.getBaseApkPath());
        }
        String[] splitCodePaths = pkg.getSplitCodePaths();
        if (!ArrayUtils.isEmpty(splitCodePaths)) {
            for (int i = 0; i < splitCodePaths.length; i++) {
                if ((pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
                    paths.add(splitCodePaths[i]);
                }
            }
        }
        return paths;
    }

    /**
     * @return a list of the base and split code paths.
     */
    public static List<String> getAllCodePaths(AndroidPackage aPkg) {
        PackageImpl pkg = (PackageImpl) aPkg;
        ArrayList<String> paths = new ArrayList<>();
        paths.add(pkg.getBaseApkPath());

        String[] splitCodePaths = pkg.getSplitCodePaths();
        if (!ArrayUtils.isEmpty(splitCodePaths)) {
            Collections.addAll(paths, splitCodePaths);
        }
        return paths;
    }

    public static SharedLibraryInfo createSharedLibraryForSdk(AndroidPackage pkg) {
        return new SharedLibraryInfo(null, pkg.getPackageName(),
                AndroidPackageUtils.getAllCodePaths(pkg),
                pkg.getSdkLibraryName(),
                pkg.getSdkLibVersionMajor(),
                SharedLibraryInfo.TYPE_SDK_PACKAGE,
                new VersionedPackage(pkg.getManifestPackageName(),
                        pkg.getLongVersionCode()),
                null, null, false /* isNative */);
    }

    public static SharedLibraryInfo createSharedLibraryForStatic(AndroidPackage pkg) {
        return new SharedLibraryInfo(null, pkg.getPackageName(),
                AndroidPackageUtils.getAllCodePaths(pkg),
                pkg.getStaticSharedLibraryName(),
                pkg.getStaticSharedLibraryVersion(),
                SharedLibraryInfo.TYPE_STATIC,
                new VersionedPackage(pkg.getManifestPackageName(),
                        pkg.getLongVersionCode()),
                null, null, false /* isNative */);
    }

    public static SharedLibraryInfo createSharedLibraryForDynamic(AndroidPackage pkg, String name) {
        return new SharedLibraryInfo(null, pkg.getPackageName(),
                AndroidPackageUtils.getAllCodePaths(pkg), name,
                SharedLibraryInfo.VERSION_UNDEFINED,
                SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(pkg.getPackageName(),
                pkg.getLongVersionCode()),
                null, null, false /* isNative */);
    }

    /**
     * Return the dex metadata files for the given package as a map
     * [code path -> dex metadata path].
     *
     * NOTE: involves I/O checks.
     */
    public static Map<String, String> getPackageDexMetadata(AndroidPackage pkg) {
        return DexMetadataHelper.buildPackageApkToDexMetadataMap
                (AndroidPackageUtils.getAllCodePaths(pkg));
    }

    /**
     * Validate the dex metadata files installed for the given package.
     *
     * @throws PackageParserException in case of errors.
     */
    public static void validatePackageDexMetadata(AndroidPackage pkg)
            throws PackageParserException {
        Collection<String> apkToDexMetadataList = getPackageDexMetadata(pkg).values();
        String packageName = pkg.getPackageName();
        long versionCode = pkg.getLongVersionCode();
        final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
        for (String dexMetadata : apkToDexMetadataList) {
            final ParseResult result = DexMetadataHelper.validateDexMetadataFile(
                    input.reset(), dexMetadata, packageName, versionCode);
            if (result.isError()) {
                throw new PackageParserException(
                        result.getErrorCode(), result.getErrorMessage(), result.getException());
            }
        }
    }

    public static NativeLibraryHelper.Handle createNativeLibraryHandle(AndroidPackage pkg)
            throws IOException {
        return NativeLibraryHelper.Handle.create(
                AndroidPackageUtils.getAllCodePaths(pkg),
                pkg.isMultiArch(),
                pkg.isExtractNativeLibrariesRequested(),
                pkg.isDebuggable()
        );
    }

    public static boolean canHaveOatDir(@NonNull PackageState packageState,
            @NonNull AndroidPackage pkg) {
        // The following app types CANNOT have oat directory
        // - non-updated system apps,
        // - incrementally installed apps.
        if (packageState.isSystem() && !packageState.isUpdatedSystemApp()) {
            return false;
        }
        if (IncrementalManager.isIncrementalPath(pkg.getPath())) {
            return false;
        }
        return true;
    }

    public static boolean hasComponentClassName(AndroidPackage pkg, String className) {
        List<ParsedActivity> activities = pkg.getActivities();
        int activitiesSize = activities.size();
        for (int index = 0; index < activitiesSize; index++) {
            if (Objects.equals(className, activities.get(index).getName())) {
                return true;
            }
        }

        List<ParsedActivity> receivers = pkg.getReceivers();
        int receiversSize = receivers.size();
        for (int index = 0; index < receiversSize; index++) {
            if (Objects.equals(className, receivers.get(index).getName())) {
                return true;
            }
        }

        List<ParsedProvider> providers = pkg.getProviders();
        int providersSize = providers.size();
        for (int index = 0; index < providersSize; index++) {
            if (Objects.equals(className, providers.get(index).getName())) {
                return true;
            }
        }

        List<ParsedService> services = pkg.getServices();
        int servicesSize = services.size();
        for (int index = 0; index < servicesSize; index++) {
            if (Objects.equals(className, services.get(index).getName())) {
                return true;
            }
        }

        List<ParsedInstrumentation> instrumentations = pkg.getInstrumentations();
        int instrumentationsSize = instrumentations.size();
        for (int index = 0; index < instrumentationsSize; index++) {
            if (Objects.equals(className, instrumentations.get(index).getName())) {
                return true;
            }
        }

        if (pkg.getBackupAgentName() != null) {
            if (Objects.equals(className, pkg.getBackupAgentName())) {
                return true;
            }
        }

        return false;
    }

    public static boolean isEncryptionAware(AndroidPackage pkg) {
        return pkg.isDirectBootAware() || pkg.isPartiallyDirectBootAware();
    }

    public static boolean isLibrary(AndroidPackage pkg) {
        // TODO(b/135203078): Can parsing just enforce these always match?
        return pkg.getSdkLibraryName() != null || pkg.getStaticSharedLibraryName() != null
                || !pkg.getLibraryNames().isEmpty();
    }

    public static int getHiddenApiEnforcementPolicy(@NonNull AndroidPackage pkg,
            @NonNull PackageStateInternal packageState) {
        boolean isAllowedToUseHiddenApis;
        if (pkg == null) {
            isAllowedToUseHiddenApis = false;
        } else if (pkg.isSignedWithPlatformKey()) {
            isAllowedToUseHiddenApis = true;
        } else if (packageState.isSystem()) {
            isAllowedToUseHiddenApis = pkg.isNonSdkApiRequested()
                    || SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(
                    pkg.getPackageName());
        } else {
            isAllowedToUseHiddenApis = false;
        }

        if (isAllowedToUseHiddenApis) {
            return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED;
        }

        // TODO(b/135203078): Handle maybeUpdateHiddenApiEnforcementPolicy. Right now it's done
        //  entirely through ApplicationInfo and shouldn't touch this specific class, but that
        //  may not always hold true.
//        if (mHiddenApiPolicy != ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT) {
//            return mHiddenApiPolicy;
//        }
        return ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED;
    }

    /**
     * Returns false iff the provided flags include the {@link PackageManager#MATCH_SYSTEM_ONLY}
     * flag and the provided package is not a system package. Otherwise returns {@code true}.
     */
    public static boolean isMatchForSystemOnly(@NonNull PackageState packageState, long flags) {
        if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
            return packageState.isSystem();
        }
        return true;
    }

    /**
     * Returns the primary ABI as parsed from the package. Used only during parsing and derivation.
     * Otherwise prefer {@link PackageState#getPrimaryCpuAbi()}.
     */
    public static String getRawPrimaryCpuAbi(AndroidPackage pkg) {
        return ((AndroidPackageHidden) pkg).getPrimaryCpuAbi();
    }

    /**
     * Returns the secondary ABI as parsed from the package. Used only during parsing and
     * derivation. Otherwise prefer {@link PackageState#getSecondaryCpuAbi()}.
     */
    public static String getRawSecondaryCpuAbi(@NonNull AndroidPackage pkg) {
        return ((AndroidPackageHidden) pkg).getSecondaryCpuAbi();
    }

    @Deprecated
    @NonNull
    public static ApplicationInfo generateAppInfoWithoutState(AndroidPackage pkg) {
        return ((AndroidPackageHidden) pkg).toAppInfoWithoutState();
    }

    /**
     * Replacement of unnecessary legacy getRealPackage. Only returns a value if the package was
     * actually renamed.
     */
    @Nullable
    public static String getRealPackageOrNull(@NonNull AndroidPackage pkg, boolean isSystem) {
        if (pkg.getOriginalPackages().isEmpty() || !isSystem) {
            return null;
        }

        return pkg.getManifestPackageName();
    }

    public static void fillVersionCodes(@NonNull AndroidPackage pkg, @NonNull PackageInfo info) {
        info.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
        info.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
    }
}
