/*
 * Copyright (C) 2017 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 android.app.admin;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * A class containing information about a pending system update.
 */
public final class SystemUpdateInfo implements Parcelable {

    /**
     * Represents it is unknown whether the system update is a security patch.
     */
    public static final int SECURITY_PATCH_STATE_UNKNOWN = 0;

    /**
     * Represents the system update is not a security patch.
     */
    public static final int SECURITY_PATCH_STATE_FALSE = 1;

    /**
     * Represents the system update is a security patch.
     */
    public static final int SECURITY_PATCH_STATE_TRUE = 2;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "SECURITY_PATCH_STATE_" }, value = {
            SECURITY_PATCH_STATE_FALSE,
            SECURITY_PATCH_STATE_TRUE,
            SECURITY_PATCH_STATE_UNKNOWN
    })
    public @interface SecurityPatchState {}

    private static final String ATTR_RECEIVED_TIME = "received-time";
    private static final String ATTR_SECURITY_PATCH_STATE = "security-patch-state";
    // Tag used to store original build fingerprint to detect when the update is applied.
    private static final String ATTR_ORIGINAL_BUILD = "original-build";

    private final long mReceivedTime;
    @SecurityPatchState
    private final int mSecurityPatchState;

    private SystemUpdateInfo(long receivedTime, @SecurityPatchState int securityPatchState) {
        this.mReceivedTime = receivedTime;
        this.mSecurityPatchState = securityPatchState;
    }

    private SystemUpdateInfo(Parcel in) {
        mReceivedTime = in.readLong();
        mSecurityPatchState = in.readInt();
    }

    /** @hide */
    @Nullable
    public static SystemUpdateInfo of(long receivedTime) {
        return receivedTime == -1
                ? null : new SystemUpdateInfo(receivedTime, SECURITY_PATCH_STATE_UNKNOWN);
    }

    /** @hide */
    @Nullable
    public static SystemUpdateInfo of(long receivedTime, boolean isSecurityPatch) {
        return receivedTime == -1 ? null : new SystemUpdateInfo(receivedTime,
                isSecurityPatch ? SECURITY_PATCH_STATE_TRUE : SECURITY_PATCH_STATE_FALSE);
    }

    /**
     * Gets time when the update was first available in milliseconds since midnight, January 1,
     * 1970 UTC.
     * @return Time in milliseconds as given by {@link System#currentTimeMillis()}
     */
    public long getReceivedTime() {
        return mReceivedTime;
    }

    /**
     * Gets whether the update is a security patch.
     * @return {@link #SECURITY_PATCH_STATE_FALSE}, {@link #SECURITY_PATCH_STATE_TRUE}, or
     *         {@link #SECURITY_PATCH_STATE_UNKNOWN}.
     */
    @SecurityPatchState
    public int getSecurityPatchState() {
        return mSecurityPatchState;
    }

    public static final @android.annotation.NonNull Creator<SystemUpdateInfo> CREATOR =
            new Creator<SystemUpdateInfo>() {
                @Override
                public SystemUpdateInfo createFromParcel(Parcel in) {
                    return new SystemUpdateInfo(in);
                }

                @Override
                public SystemUpdateInfo[] newArray(int size) {
                    return new SystemUpdateInfo[size];
                }
            };

    /** @hide */
    public void writeToXml(XmlSerializer out, String tag) throws IOException {
        out.startTag(null, tag);
        out.attribute(null, ATTR_RECEIVED_TIME, String.valueOf(mReceivedTime));
        out.attribute(null, ATTR_SECURITY_PATCH_STATE, String.valueOf(mSecurityPatchState));
        out.attribute(null, ATTR_ORIGINAL_BUILD , Build.FINGERPRINT);
        out.endTag(null, tag);
    }

    /** @hide */
    @Nullable
    public static SystemUpdateInfo readFromXml(XmlPullParser parser) {
        // If an OTA has been applied (build fingerprint has changed), discard stale info.
        final String buildFingerprint = parser.getAttributeValue(null, ATTR_ORIGINAL_BUILD );
        if (!Build.FINGERPRINT.equals(buildFingerprint)) {
            return null;
        }
        final long receivedTime =
                Long.parseLong(parser.getAttributeValue(null, ATTR_RECEIVED_TIME));
        final int securityPatchState =
                Integer.parseInt(parser.getAttributeValue(null, ATTR_SECURITY_PATCH_STATE));
        return new SystemUpdateInfo(receivedTime, securityPatchState);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(getReceivedTime());
        dest.writeInt(getSecurityPatchState());
    }

    @Override
    public String toString() {
        return String.format("SystemUpdateInfo (receivedTime = %d, securityPatchState = %s)",
                mReceivedTime, securityPatchStateToString(mSecurityPatchState));
    }

    private static String securityPatchStateToString(@SecurityPatchState int state) {
        switch (state) {
            case SECURITY_PATCH_STATE_FALSE:
                return "false";
            case SECURITY_PATCH_STATE_TRUE:
                return "true";
            case SECURITY_PATCH_STATE_UNKNOWN:
                return "unknown";
            default:
                throw new IllegalArgumentException("Unrecognized security patch state: " + state);
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SystemUpdateInfo that = (SystemUpdateInfo) o;
        return mReceivedTime == that.mReceivedTime
                && mSecurityPatchState == that.mSecurityPatchState;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mReceivedTime, mSecurityPatchState);
    }
}
