package net.northking.cctp.upperComputer.driver.agent.command.data;

import java.util.Arrays;

public class PackageInfo {

    //region flag
    /**
     * Value for {@link #flags}: if set, this application is installed in the device's system image.
     * This should not be used to make security decisions. Instead, rely on
     * signature checks} or
     * <a href="https://developer.android.com/training/articles/security-tips#Permissions">permissions</a>.
     *
     * <p><b>Warning:</b> Note that does flag not behave the same as
     * {@code signatureOrSystem}.
     */
    public static final int FLAG_SYSTEM = 1 << 0;

    /**
     * Value for {@link #flags}: set to true if this application would like to
     * allow debugging of its
     * code, even when installed on a non-development system.  Comes
     * android:debuggable} of the &lt;application&gt; tag.
     */
    public static final int FLAG_DEBUGGABLE = 1 << 1;

    /**
     * Value for {@link #flags}: set to true if this application has code
     * associated with it.  Comes
     * android:hasCode} of the &lt;application&gt; tag.
     */
    public static final int FLAG_HAS_CODE = 1 << 2;

    /**
     * Value for {@link #flags}: set to true if this application is persistent.
     * android:persistent} of the &lt;application&gt; tag.
     */
    public static final int FLAG_PERSISTENT = 1 << 3;

    /**
     * Value for {@link #flags}: set to true if this application holds the
     * device is running in factory test mode.
     */
    public static final int FLAG_FACTORY_TEST = 1 << 4;

    /**
     * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
     * android:allowTaskReparenting} of the &lt;application&gt; tag.
     */
    public static final int FLAG_ALLOW_TASK_REPARENTING = 1 << 5;

    /**
     * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
     * android:allowClearUserData} of the &lt;application&gt; tag.
     */
    public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1 << 6;

    /**
     * Value for {@link #flags}: this is set if this application has been
     * installed as an update to a built-in system application.
     */
    public static final int FLAG_UPDATED_SYSTEM_APP = 1 << 7;

    /**
     * Value for {@link #flags}: this is set if the application has specified
     * android:testOnly} to be true.
     */
    public static final int FLAG_TEST_ONLY = 1 << 8;

    /**
     * Value for {@link #flags}: true when the application's window can be
     * reduced in size for smaller screens.  Corresponds to
     * android:smallScreens}.
     */
    public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1 << 9;

    /**
     * Value for {@link #flags}: true when the application's window can be
     * displayed on normal screens.  Corresponds to
     * android:normalScreens}.
     */
    public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1 << 10;

    /**
     * Value for {@link #flags}: true when the application's window can be
     * increased in size for larger screens.  Corresponds to
     * android:largeScreens}.
     */
    public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1 << 11;

    /**
     * Value for {@link #flags}: true when the application knows how to adjust
     * its UI for different screen sizes.  Corresponds to
     * android:resizeable}.
     */
    public static final int FLAG_RESIZEABLE_FOR_SCREENS = 1 << 12;

    /**
     * Value for {@link #flags}: true when the application knows how to
     * accommodate different screen densities.  Corresponds to
     * android:anyDensity}.
     *
     * @deprecated Set by default when targeting API 4 or higher and apps
     * should not set this to false.
     */
    @Deprecated
    public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 1 << 13;

    /**
     * Value for {@link #flags}: set to true if this application would like to
     * request the VM to operate under the safe mode. Comes from
     * android:vmSafeMode} of the &lt;application&gt; tag.
     */
    public static final int FLAG_VM_SAFE_MODE = 1 << 14;

    /**
     * Value for {@link #flags}: set to <code>false</code> if the application does not wish
     * to permit any OS-driven backups of its data; <code>true</code> otherwise.
     *
     * <p>Comes from the
     * attribute of the &lt;application&gt; tag.
     */
    public static final int FLAG_ALLOW_BACKUP = 1 << 15;

    /**
     * Value for {@link #flags}: set to <code>false</code> if the application must be kept
     * in memory following a full-system restore operation; <code>true</code> otherwise.
     * Ordinarily, during a full system restore operation each application is shut down
     * following execution of its agent's onRestore() method.  Setting this attribute to
     * <code>false</code> prevents this.  Most applications will not need to set this attribute.
     *
     * <p>If
     * is set to <code>false</code> or no
     * is specified, this flag will be ignored.
     *
     * <p>Comes from the
     * attribute of the &lt;application&gt; tag.
     */
    public static final int FLAG_KILL_AFTER_RESTORE = 1 << 16;

    /**
     * Value for {@link #flags}: Set to <code>true</code> if the application's backup
     * agent claims to be able to handle restore data even "from the future,"
     * i.e. from versions of the application with a versionCode greater than
     * the one currently installed on the device.  <i>Use with caution!</i>  By default
     * this attribute is <code>false</code> and the Backup Manager will ensure that data
     * from "future" versions of the application are never supplied during a restore operation.
     *
     * <p>If
     * is set to <code>false</code> or no
     * is specified, this flag will be ignored.
     *
     * <p>Comes from the
     * attribute of the &lt;application&gt; tag.
     */
    public static final int FLAG_RESTORE_ANY_VERSION = 1 << 17;

    /**
     * Value for {@link #flags}: Set to true if the application is
     * currently installed on external/removable/unprotected storage.  Such
     * applications may not be available if their storage is not currently
     * mounted.  When the storage it is on is not available, it will look like
     * the application has been uninstalled (its .apk is no longer available)
     * but its persistent data is not removed.
     */
    public static final int FLAG_EXTERNAL_STORAGE = 1 << 18;

    /**
     * Value for {@link #flags}: true when the application's window can be
     * increased in size for extra large screens.  Corresponds to
     * android:xlargeScreens}.
     */
    public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1 << 19;

    /**
     * Value for {@link #flags}: true when the application has requested a
     * large heap for its processes.  Corresponds to
     * android:largeHeap}.
     */
    public static final int FLAG_LARGE_HEAP = 1 << 20;

    /**
     * Value for {@link #flags}: true if this application's package is in
     * the stopped state.
     */
    public static final int FLAG_STOPPED = 1 << 21;

    /**
     * Value for {@link #flags}: true  when the application is willing to support
     * RTL (right to left). All activities will inherit this value.
     * <p>
     * activity's manifest.
     * <p>
     * Default value is false (no support for RTL).
     */
    public static final int FLAG_SUPPORTS_RTL = 1 << 22;

    /**
     * Value for {@link #flags}: true if the application is currently
     * installed for the calling user.
     */
    public static final int FLAG_INSTALLED = 1 << 23;

    /**
     * Value for {@link #flags}: true if the application only has its
     * data installed; the application package itself does not currently
     * exist on the device.
     */
    public static final int FLAG_IS_DATA_ONLY = 1 << 24;

    /**
     * Value for {@link #flags}: true if the application was declared to be a
     * game, or false if it is a non-game application.
     *
     */
    @Deprecated
    public static final int FLAG_IS_GAME = 1 << 25;

    /**
     * Value for {@link #flags}: {@code true} if the application asks that only
     * full-data streaming backups of its data be performed even though it defines
     * indicates that the app will manage its backed-up data via incremental
     * key/value updates.
     */
    public static final int FLAG_FULL_BACKUP_ONLY = 1 << 26;

    /**
     * Value for {@link #flags}: {@code true} if the application may use cleartext network traffic
     * (e.g., HTTP rather than HTTPS; WebSockets rather than WebSockets Secure; XMPP, IMAP, SMTP
     * without STARTTLS or TLS). If {@code false}, the app declares that it does not intend to use
     * cleartext network traffic, in which case platform components (e.g., HTTP stacks,
     * {@code DownloadManager}, {@code MediaPlayer}) will refuse app's requests to use cleartext
     * traffic. Third-party libraries are encouraged to honor this flag as well.
     *
     * <p>NOTE: {@code WebView} honors this flag for applications targeting API level 26 and up.
     *
     * <p>This flag is ignored on Android N and above if an Android Network Security Config is
     * present.
     *
     * <p>This flag comes from
     * android:usesCleartextTraffic} of the &lt;application&gt; tag.
     */
    public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1 << 27;

    /**
     * When set installer extracts native libs from .apk files.
     */
    public static final int FLAG_EXTRACT_NATIVE_LIBS = 1 << 28;

    /**
     * Value for {@link #flags}: {@code true} when the application's rendering
     * should be hardware accelerated.
     */
    public static final int FLAG_HARDWARE_ACCELERATED = 1 << 29;

    /**
     * Value for {@link #flags}: true if this application's package is in
     * the suspended state.
     */
    public static final int FLAG_SUSPENDED = 1 << 30;

    /**
     * Value for {@link #flags}: true if code from this application will need to be
     * loaded into other applications' processes. On devices that support multiple
     * instruction sets, this implies the code might be loaded into a process that's
     * using any of the devices supported instruction sets.
     *
     * <p> The system might treat such applications specially, for eg., by
     * extracting the application's native libraries for all supported instruction
     * sets or by compiling the application's dex code for all supported instruction
     * sets.
     */
    public static final int FLAG_MULTIARCH = 1 << 31;
    //endregion flag

    private String packageName;
    private int flags;
    private String className = null;
    private String processName;
    private int compatibleWidthLimitDp;
    private String manageSpaceActivityName = null;
    private String backupAgentName = null;
    /**
     * APK路径
     */
    private String sourceDir;
    /**
     * 数据路径
     */
    private String dataDir;
    private int uid;
    /**
     * 应用名称
     */
    private String label;
    private String[] splitNames;
    /**
     * 应用版本号
     */
    private long versionCode;
    /**
     * 应用版本名
     */
    private String versionName;
    private int baseRevisionCode;
    private int[] splitRevisionCodes;
    private String sharedUserId;
    private int sharedUserLabel;
    private long firstInstallTime;
    private long lastUpdateTime;
    private int[] gids;
    private String[] requestedPermissions;
    private int[] requestedPermissionFlags;
    private String[] signatures;
    private String[] apkContentsSigners;
    private String[] signingCertificateHistory;
    private boolean hasMultipleSigners = false;
    private boolean hasPastSigningCertificates = false;
    private boolean isApex = false;

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public int getFlags() {
        return flags;
    }

    public void setFlags(int flags) {
        this.flags = flags;
    }

    /**
     * @hide
     */
    public boolean isSystemApp() {
        return (flags & FLAG_SYSTEM) != 0;
    }

    /**
     * @hide
     */
    public boolean isUpdatedSystemApp() {
        return (flags & FLAG_UPDATED_SYSTEM_APP) != 0;
    }


    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getProcessName() {
        return processName;
    }

    public void setProcessName(String processName) {
        this.processName = processName;
    }

    public int getCompatibleWidthLimitDp() {
        return compatibleWidthLimitDp;
    }

    public void setCompatibleWidthLimitDp(int compatibleWidthLimitDp) {
        this.compatibleWidthLimitDp = compatibleWidthLimitDp;
    }

    public String getManageSpaceActivityName() {
        return manageSpaceActivityName;
    }

    public void setManageSpaceActivityName(String manageSpaceActivityName) {
        this.manageSpaceActivityName = manageSpaceActivityName;
    }

    public String getBackupAgentName() {
        return backupAgentName;
    }

    public void setBackupAgentName(String backupAgentName) {
        this.backupAgentName = backupAgentName;
    }

    public String getSourceDir() {
        return sourceDir;
    }

    public void setSourceDir(String sourceDir) {
        this.sourceDir = sourceDir;
    }

    public String getDataDir() {
        return dataDir;
    }

    public void setDataDir(String dataDir) {
        this.dataDir = dataDir;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String[] getSplitNames() {
        return splitNames;
    }

    public void setSplitNames(String[] splitNames) {
        this.splitNames = splitNames;
    }

    public long getVersionCode() {
        return versionCode;
    }

    public void setVersionCode(long versionCode) {
        this.versionCode = versionCode;
    }

    public String getVersionName() {
        return versionName;
    }

    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    public int getBaseRevisionCode() {
        return baseRevisionCode;
    }

    public void setBaseRevisionCode(int baseRevisionCode) {
        this.baseRevisionCode = baseRevisionCode;
    }

    public int[] getSplitRevisionCodes() {
        return splitRevisionCodes;
    }

    public void setSplitRevisionCodes(int[] splitRevisionCodes) {
        this.splitRevisionCodes = splitRevisionCodes;
    }

    public String getSharedUserId() {
        return sharedUserId;
    }

    public void setSharedUserId(String sharedUserId) {
        this.sharedUserId = sharedUserId;
    }

    public int getSharedUserLabel() {
        return sharedUserLabel;
    }

    public void setSharedUserLabel(int sharedUserLabel) {
        this.sharedUserLabel = sharedUserLabel;
    }

    public long getFirstInstallTime() {
        return firstInstallTime;
    }

    public void setFirstInstallTime(long firstInstallTime) {
        this.firstInstallTime = firstInstallTime;
    }

    public long getLastUpdateTime() {
        return lastUpdateTime;
    }

    public void setLastUpdateTime(long lastUpdateTime) {
        this.lastUpdateTime = lastUpdateTime;
    }

    public int[] getGids() {
        return gids;
    }

    public void setGids(int[] gids) {
        this.gids = gids;
    }

    public String[] getRequestedPermissions() {
        return requestedPermissions;
    }

    public void setRequestedPermissions(String[] requestedPermissions) {
        this.requestedPermissions = requestedPermissions;
    }

    public int[] getRequestedPermissionFlags() {
        return requestedPermissionFlags;
    }

    public void setRequestedPermissionFlags(int[] requestedPermissionFlags) {
        this.requestedPermissionFlags = requestedPermissionFlags;
    }

    public String[] getSignatures() {
        return signatures;
    }

    public void setSignatures(String[] signatures) {
        this.signatures = signatures;
    }

    public String[] getApkContentsSigners() {
        return apkContentsSigners;
    }

    public void setApkContentsSigners(String[] apkContentsSigners) {
        this.apkContentsSigners = apkContentsSigners;
    }

    public String[] getSigningCertificateHistory() {
        return signingCertificateHistory;
    }

    public void setSigningCertificateHistory(String[] signingCertificateHistory) {
        this.signingCertificateHistory = signingCertificateHistory;
    }

    public boolean isHasMultipleSigners() {
        return hasMultipleSigners;
    }

    public void setHasMultipleSigners(boolean hasMultipleSigners) {
        this.hasMultipleSigners = hasMultipleSigners;
    }

    public boolean isHasPastSigningCertificates() {
        return hasPastSigningCertificates;
    }

    public void setHasPastSigningCertificates(boolean hasPastSigningCertificates) {
        this.hasPastSigningCertificates = hasPastSigningCertificates;
    }

    public boolean isApex() {
        return isApex;
    }

    public void setApex(boolean apex) {
        isApex = apex;
    }

    @Override
    public String toString() {
        return "PackageInfo{" +
                "packageName='" + packageName + '\'' +
                ", flags=" + flags +
                ", className='" + className + '\'' +
                ", processName='" + processName + '\'' +
                ", compatibleWidthLimitDp=" + compatibleWidthLimitDp +
                ", manageSpaceActivityName='" + manageSpaceActivityName + '\'' +
                ", backupAgentName='" + backupAgentName + '\'' +
                ", sourceDir='" + sourceDir + '\'' +
                ", dataDir='" + dataDir + '\'' +
                ", uid=" + uid +
                ", label='" + label + '\'' +
                ", splitNames=" + Arrays.toString(splitNames) +
                ", versionCode=" + versionCode +
                ", versionName='" + versionName + '\'' +
                ", baseRevisionCode=" + baseRevisionCode +
                ", splitRevisionCodes=" + Arrays.toString(splitRevisionCodes) +
                ", sharedUserId='" + sharedUserId + '\'' +
                ", sharedUserLabel=" + sharedUserLabel +
                ", firstInstallTime=" + firstInstallTime +
                ", lastUpdateTime=" + lastUpdateTime +
                ", gids=" + Arrays.toString(gids) +
                ", requestedPermissions=" + Arrays.toString(requestedPermissions) +
                ", requestedPermissionFlags=" + Arrays.toString(requestedPermissionFlags) +
                ", signatures=" + Arrays.toString(signatures) +
                ", apkContentsSigners=" + Arrays.toString(apkContentsSigners) +
                ", signingCertificateHistory=" + Arrays.toString(signingCertificateHistory) +
                ", hasMultipleSigners=" + hasMultipleSigners +
                ", hasPastSigningCertificates=" + hasPastSigningCertificates +
                ", isApex=" + isApex +
                '}';
    }
}
