/*
 * Copyright 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 android.app.blob;

import static android.app.blob.XmlTags.ATTR_ALGO;
import static android.app.blob.XmlTags.ATTR_DIGEST;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
import static android.app.blob.XmlTags.ATTR_LABEL;
import static android.app.blob.XmlTags.ATTR_TAG;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;

import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;

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

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
 * An identifier to represent a blob.
 */
// TODO: use datagen tool?
public final class BlobHandle implements Parcelable {
    /** @hide */
    public static final String ALGO_SHA_256 = "SHA-256";

    private static final String[] SUPPORTED_ALGOS = {
            ALGO_SHA_256
    };

    private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters

    /**
     * Cyrptographically secure hash algorithm used to generate hash of the blob this handle is
     * representing.
     *
     * @hide
     */
    @NonNull public final String algorithm;

    /**
     * Hash of the blob this handle is representing using {@link #algorithm}.
     *
     * @hide
     */
    @NonNull public final byte[] digest;

    /**
     * Label of the blob that can be surfaced to the user.
     * @hide
     */
    @NonNull public final CharSequence label;

    /**
     * Time in milliseconds after which the blob should be invalidated and not
     * allowed to be accessed by any other app, in {@link System#currentTimeMillis()} timebase.
     *
     * @hide
     */
    @CurrentTimeMillisLong public final long expiryTimeMillis;

    /**
     * An opaque {@link String} associated with the blob.
     *
     * @hide
     */
    @NonNull public final String tag;

    private BlobHandle(String algorithm, byte[] digest, CharSequence label, long expiryTimeMillis,
            String tag) {
        this.algorithm = algorithm;
        this.digest = digest;
        this.label = label;
        this.expiryTimeMillis = expiryTimeMillis;
        this.tag = tag;
    }

    private BlobHandle(Parcel in) {
        this.algorithm = in.readString();
        this.digest = in.createByteArray();
        this.label = in.readCharSequence();
        this.expiryTimeMillis = in.readLong();
        this.tag = in.readString();
    }

    /** @hide */
    public static @NonNull BlobHandle create(@NonNull String algorithm, @NonNull byte[] digest,
            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
            @NonNull String tag) {
        final BlobHandle handle = new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
        handle.assertIsValid();
        return handle;
    }

    /**
     * Create a new blob identifier.
     *
     * <p> For two objects of {@link BlobHandle} to be considered equal, the following arguments
     * must be equal:
     * <ul>
     * <li> {@code digest}
     * <li> {@code label}
     * <li> {@code expiryTimeMillis}
     * <li> {@code tag}
     * </ul>
     *
     * @param digest the SHA-256 hash of the blob this is representing.
     * @param label a label indicating what the blob is, that can be surfaced to the user.
     * @param expiryTimeMillis the time in secs after which the blob should be invalidated and not
     *                         allowed to be accessed by any other app,
     *                         in {@link System#currentTimeMillis()} timebase or {@code 0} to
     *                         indicate that there is no expiry time associated with this blob.
     * @param tag an opaque {@link String} associated with the blob. The length of the tag
     *            cannot be more than 128 characters.
     *
     * @return a new instance of {@link BlobHandle} object.
     */
    public static @NonNull BlobHandle createWithSha256(@NonNull byte[] digest,
            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
            @NonNull String tag) {
        return create(ALGO_SHA_256, digest, label, expiryTimeMillis, tag);
    }

    /**
     * Returns the SHA-256 hash of the blob that this object is representing.
     *
     * @see #createWithSha256(byte[], CharSequence, long, String)
     */
    public @NonNull byte[] getSha256Digest() {
        return digest;
    }

    /**
     * Returns the label associated with the blob that this object is representing.
     *
     * @see #createWithSha256(byte[], CharSequence, long, String)
     */
    public @NonNull CharSequence getLabel() {
        return label;
    }

    /**
     * Returns the expiry time in milliseconds of the blob that this object is representing, in
     *         {@link System#currentTimeMillis()} timebase.
     *
     * @see #createWithSha256(byte[], CharSequence, long, String)
     */
    public @CurrentTimeMillisLong long getExpiryTimeMillis() {
        return expiryTimeMillis;
    }

    /**
     * Returns the opaque {@link String} associated with the blob this object is representing.
     *
     * @see #createWithSha256(byte[], CharSequence, long, String)
     */
    public @NonNull String getTag() {
        return tag;
    }

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

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(algorithm);
        dest.writeByteArray(digest);
        dest.writeCharSequence(label);
        dest.writeLong(expiryTimeMillis);
        dest.writeString(tag);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || !(obj instanceof BlobHandle)) {
            return false;
        }
        final BlobHandle other = (BlobHandle) obj;
        return this.algorithm.equals(other.algorithm)
                && Arrays.equals(this.digest, other.digest)
                && this.label.equals(other.label)
                && this.expiryTimeMillis == other.expiryTimeMillis
                && this.tag.equals(tag);
    }

    @Override
    public int hashCode() {
        return Objects.hash(algorithm, Arrays.hashCode(digest), label, expiryTimeMillis, tag);
    }

    /** @hide */
    public void dump(IndentingPrintWriter fout, boolean dumpFull) {
        if (dumpFull) {
            fout.println("algo: " + algorithm);
            fout.println("digest: " + (dumpFull ? encodeDigest() : safeDigest()));
            fout.println("label: " + label);
            fout.println("expiryMs: " + expiryTimeMillis);
            fout.println("tag: " + tag);
        } else {
            fout.println(toString());
        }
    }

    /** @hide */
    public void assertIsValid() {
        Preconditions.checkArgumentIsSupported(SUPPORTED_ALGOS, algorithm);
        Preconditions.checkByteArrayNotEmpty(digest, "digest");
        Preconditions.checkStringNotEmpty(label, "label must not be null");
        Preconditions.checkArgumentNonnegative(expiryTimeMillis,
                "expiryTimeMillis must not be negative");
        Preconditions.checkStringNotEmpty(tag, "tag must not be null");
        Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
    }

    @Override
    public String toString() {
        return "BlobHandle {"
                + "algo:" + algorithm + ","
                + "digest:" + safeDigest() + ","
                + "label:" + label + ","
                + "expiryMs:" + expiryTimeMillis + ","
                + "tag:" + tag
                + "}";
    }

    private String safeDigest() {
        final String digestStr = encodeDigest();
        return digestStr.substring(0, 2) + ".." + digestStr.substring(digestStr.length() - 2);
    }

    private String encodeDigest() {
        return Base64.encodeToString(digest, Base64.NO_WRAP);
    }

    /** @hide */
    public boolean isExpired() {
        return expiryTimeMillis != 0 && expiryTimeMillis < System.currentTimeMillis();
    }

    public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
        @Override
        public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
            return new BlobHandle(source);
        }

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

    /** @hide */
    public void writeToXml(@NonNull XmlSerializer out) throws IOException {
        XmlUtils.writeStringAttribute(out, ATTR_ALGO, algorithm);
        XmlUtils.writeByteArrayAttribute(out, ATTR_DIGEST, digest);
        XmlUtils.writeStringAttribute(out, ATTR_LABEL, label);
        XmlUtils.writeLongAttribute(out, ATTR_EXPIRY_TIME, expiryTimeMillis);
        XmlUtils.writeStringAttribute(out, ATTR_TAG, tag);
    }

    /** @hide */
    @NonNull
    public static BlobHandle createFromXml(@NonNull XmlPullParser in) throws IOException {
        final String algo = XmlUtils.readStringAttribute(in, ATTR_ALGO);
        final byte[] digest = XmlUtils.readByteArrayAttribute(in, ATTR_DIGEST);
        final CharSequence label = XmlUtils.readStringAttribute(in, ATTR_LABEL);
        final long expiryTimeMs = XmlUtils.readLongAttribute(in, ATTR_EXPIRY_TIME);
        final String tag = XmlUtils.readStringAttribute(in, ATTR_TAG);

        return BlobHandle.create(algo, digest, label, expiryTimeMs, tag);
    }
}
