/*
 * 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 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);
    }
}
