/*
 * Copyright (C) 2021 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.dex;

import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED;
import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY;
import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;
import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK;

import android.os.SystemClock;
import android.util.Slog;
import android.util.jar.StrictJarFile;

import com.android.internal.art.ArtStatsLog;
import com.android.server.pm.PackageManagerService;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;

/** Utils class to report ART metrics to statsd. */
public class ArtStatsLogUtils {
    private static final String TAG = ArtStatsLogUtils.class.getSimpleName();
    private static final String PROFILE_DEX_METADATA = "primary.prof";
    private static final String VDEX_DEX_METADATA = "primary.vdex";

    private static final int ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY =
            ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY;
    private static final int ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED =
            ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED;
    private static final int ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED =
            ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;

    private static final int ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK =
            ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
    private static final int ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK =
            ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK;

    private static final Map<Integer, Integer> COMPILATION_REASON_MAP = new HashMap();

    static {
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_FIRST_BOOT, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_FIRST_BOOT);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_BOOT_AFTER_OTA, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BOOT);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_POST_BOOT, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_POST_BOOT);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_FAST, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_FAST);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_SECONDARY,
                ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_DOWNGRADED,
                ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_SECONDARY_DOWNGRADED,
                ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_BACKGROUND_DEXOPT, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BG_DEXOPT);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_AB_OTA, ArtStatsLog.
                ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_AB_OTA);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE,
                ArtStatsLog.
                        ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INACTIVE);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_CMDLINE,
                ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_CMDLINE);
        COMPILATION_REASON_MAP.put(PackageManagerService.REASON_SHARED,
                ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_SHARED);
    }

    private static final Map<String, Integer> COMPILE_FILTER_MAP = new HashMap();

    static {
        COMPILE_FILTER_MAP.put("error", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ERROR);
        COMPILE_FILTER_MAP.put("unknown", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN);
        COMPILE_FILTER_MAP.put("assume-verified", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ASSUMED_VERIFIED);
        COMPILE_FILTER_MAP.put("extract", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EXTRACT);
        COMPILE_FILTER_MAP.put("verify", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_VERIFY);
        COMPILE_FILTER_MAP.put("quicken", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_QUICKEN);
        COMPILE_FILTER_MAP.put("space-profile", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE_PROFILE);
        COMPILE_FILTER_MAP.put("space", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE);
        COMPILE_FILTER_MAP.put("speed-profile", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED_PROFILE);
        COMPILE_FILTER_MAP.put("speed", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED);
        COMPILE_FILTER_MAP.put("everything-profile", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING_PROFILE);
        COMPILE_FILTER_MAP.put("everything", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING);
        COMPILE_FILTER_MAP.put("run-from-apk", ArtStatsLog.
                ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK);
        COMPILE_FILTER_MAP.put("run-from-apk-fallback",
                ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK);
        COMPILE_FILTER_MAP.put("run-from-vdex-fallback",
                ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK);
    }

    private static final Map<String, Integer> ISA_MAP = new HashMap();

    static {
        ISA_MAP.put("arm", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_ARM);
        ISA_MAP.put("arm64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_ARM64);
        ISA_MAP.put("x86", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_X86);
        ISA_MAP.put("x86_64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_X86_64);
        ISA_MAP.put("mips", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_MIPS);
        ISA_MAP.put("mips64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_MIPS64);
    }

    public static void writeStatsLog(
            ArtStatsLogger logger,
            long sessionId,
            String compilerFilter,
            int uid,
            long compileTime,
            String dexMetadataPath,
            int compilationReason,
            int result,
            int apkType,
            String isa,
            String apkPath) {
        int dexMetadataType = getDexMetadataType(dexMetadataPath);
        logger.write(
                sessionId,
                uid,
                compilationReason,
                compilerFilter,
                ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_RESULT_CODE,
                result,
                dexMetadataType,
                apkType,
                isa);
        logger.write(
                sessionId,
                uid,
                compilationReason,
                compilerFilter,
                ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_COUNTER_BYTES,
                getDexBytes(apkPath),
                dexMetadataType,
                apkType,
                isa);
        logger.write(
                sessionId,
                uid,
                compilationReason,
                compilerFilter,
                ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME_COUNTER_MILLIS,
                compileTime,
                dexMetadataType,
                apkType,
                isa);
    }

    public static int getApkType(String path, String baseApkPath, String[] splitApkPaths) {
        if (path.equals(baseApkPath)) {
            return ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_BASE;
        } else if(Arrays.stream(splitApkPaths).anyMatch(p->p.equals(path))) {
            return ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_SPLIT;
        } else{
            return ArtStatsLog.ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_UNKNOWN;
        }
    }

    private static long getDexBytes(String apkPath) {
        StrictJarFile jarFile = null;
        long dexBytes = 0;
        try {
            jarFile = new StrictJarFile(apkPath,
                    /*verify=*/ false,
                    /*signatureSchemeRollbackProtectionsEnforced=*/ false);
            Iterator<ZipEntry> it = jarFile.iterator();
            Pattern p = Pattern.compile("classes(\\d)*[.]dex");
            Matcher m = p.matcher("");
            while (it.hasNext()) {
                ZipEntry entry = it.next();
                m.reset(entry.getName());
                if (m.matches()) {
                    dexBytes += entry.getSize();
                }
            }
            return dexBytes;
        } catch (IOException ignore) {
            Slog.e(TAG, "Error when parsing APK " + apkPath);
            return -1L;
        } finally {
            try {
                if (jarFile != null) {
                    jarFile.close();
                }
            } catch (IOException ignore) {
            }
        }
    }

    private static int getDexMetadataType(String dexMetadataPath) {
        if (dexMetadataPath == null) {
            return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_NONE;
        }
        StrictJarFile jarFile = null;
        try {
            jarFile = new StrictJarFile(dexMetadataPath,
                    /*verify=*/ false,
                    /*signatureSchemeRollbackProtectionsEnforced=*/false);
            boolean hasProfile = findFileName(jarFile, PROFILE_DEX_METADATA);
            boolean hasVdex = findFileName(jarFile, VDEX_DEX_METADATA);
            if (hasProfile && hasVdex) {
                return ArtStatsLog.
                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE_AND_VDEX;
            } else if (hasProfile) {
                return ArtStatsLog.
                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_PROFILE;
            } else if (hasVdex) {
                return ArtStatsLog.
                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_VDEX;
            } else {
                return ArtStatsLog.
                    ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_UNKNOWN;
            }
        } catch (IOException ignore) {
            Slog.e(TAG, "Error when parsing dex metadata " + dexMetadataPath);
            return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_ERROR;
        } finally {
            try {
                if (jarFile != null) {
                    jarFile.close();
                }
            } catch (IOException ignore) {
            }
        }
    }

    private static boolean findFileName(StrictJarFile jarFile, String filename) throws IOException {
        Iterator<ZipEntry> it = jarFile.iterator();
        while (it.hasNext()) {
            ZipEntry entry = it.next();
            if (entry.getName().equals(filename)) {
                return true;
            }
        }
        return false;
    }

    public static class ArtStatsLogger {
        public void write(
                long sessionId,
                int uid,
                int compilationReason,
                String compilerFilter,
                int kind,
                long value,
                int dexMetadataType,
                int apkType,
                String isa) {
            ArtStatsLog.write(
                    ArtStatsLog.ART_DATUM_REPORTED,
                    sessionId,
                    uid,
                    COMPILE_FILTER_MAP.getOrDefault(compilerFilter, ArtStatsLog.
                            ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN),
                    COMPILATION_REASON_MAP.getOrDefault(compilationReason, ArtStatsLog.
                            ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN),
                    /*timestamp_millis=*/ SystemClock.uptimeMillis(),
                    ArtStatsLog.ART_DATUM_REPORTED__THREAD_TYPE__ART_THREAD_MAIN,
                    kind,
                    value,
                    dexMetadataType,
                    apkType,
                    ISA_MAP.getOrDefault(isa,
                            ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_UNKNOWN));
        }
    }
}
