/*
 * 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.view.autofill;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;

/**
 * A unique identifier for an autofill node inside an {@link android.app.Activity}.
 */
public final class AutofillId implements Parcelable {

    /** @hide */
    public static final int NO_SESSION = 0;

    private static final int FLAG_IS_VIRTUAL_INT = 0x1;
    private static final int FLAG_IS_VIRTUAL_LONG = 0x2;
    private static final int FLAG_HAS_SESSION = 0x4;

    private final int mViewId;
    private int mFlags;
    private final int mVirtualIntId;
    private final long mVirtualLongId;
    private int mSessionId;

    /** @hide */
    @TestApi
    public AutofillId(int id) {
        this(/* flags= */ 0, id, View.NO_ID, NO_SESSION);
    }

    /** @hide */
    @TestApi
    public AutofillId(@NonNull AutofillId hostId, int virtualChildId) {
        this(FLAG_IS_VIRTUAL_INT, hostId.mViewId, virtualChildId, NO_SESSION);
    }

    /** @hide */
    @TestApi
    public AutofillId(int hostId, int virtualChildId) {
        this(FLAG_IS_VIRTUAL_INT, hostId, virtualChildId, NO_SESSION);
    }

    /** @hide */
    @TestApi
    public AutofillId(@NonNull AutofillId hostId, long virtualChildId, int sessionId) {
        this(FLAG_IS_VIRTUAL_LONG | FLAG_HAS_SESSION, hostId.mViewId, virtualChildId, sessionId);
    }

    private AutofillId(int flags, int parentId, long virtualChildId, int sessionId) {
        mFlags = flags;
        mViewId = parentId;
        mVirtualIntId = ((flags & FLAG_IS_VIRTUAL_INT) != 0) ? (int) virtualChildId : View.NO_ID;
        mVirtualLongId = ((flags & FLAG_IS_VIRTUAL_LONG) != 0) ? virtualChildId : View.NO_ID;
        mSessionId = sessionId;
    }

    /** @hide */
    @NonNull
    @TestApi
    public static AutofillId withoutSession(@NonNull AutofillId id) {
        final int flags = id.mFlags & ~FLAG_HAS_SESSION;
        final long virtualChildId =
                ((id.mFlags & FLAG_IS_VIRTUAL_LONG) != 0) ? id.mVirtualLongId
                        : id.mVirtualIntId;
        return new AutofillId(flags, id.mViewId, virtualChildId, NO_SESSION);
    }

    /** @hide */
    public int getViewId() {
        return mViewId;
    }

    /**
     * Gets the virtual child id.
     *
     * <p>Should only be used on subsystems where such id is represented by an {@code int}
     * (Assist and Autofill).
     *
     * @hide
     */
    public int getVirtualChildIntId() {
        return mVirtualIntId;
    }

    /**
     * Gets the virtual child id.
     *
     * <p>Should only be used on subsystems where such id is represented by a {@code long}
     * (ContentCapture).
     *
     * @hide
     */
    public long getVirtualChildLongId() {
        return mVirtualLongId;
    }

    /**
     * Checks whether this node represents a virtual child, whose id is represented by an
     * {@code int}.
     *
     * <p>Should only be used on subsystems where such id is represented by an {@code int}
     * (Assist and Autofill).
     *
     * @hide
     */
    public boolean isVirtualInt() {
        return (mFlags & FLAG_IS_VIRTUAL_INT) != 0;
    }

    /**
     * Checks whether this node represents a virtual child, whose id is represented by an
     * {@code long}.
     *
     * <p>Should only be used on subsystems where such id is represented by a {@code long}
     * (ContentCapture).
     *
     * @hide
     */
    public boolean isVirtualLong() {
        return (mFlags & FLAG_IS_VIRTUAL_LONG) != 0;
    }

    /**
     * Checks whether this node represents a non-virtual child.
     *
     * @hide
     */
    public boolean isNonVirtual() {
        return !isVirtualInt() && !isVirtualLong();
    }

    /** @hide */
    public boolean hasSession() {
        return (mFlags & FLAG_HAS_SESSION) != 0;
    }

    /** @hide */
    public int getSessionId() {
        return mSessionId;
    }

    /** @hide */
    public void setSessionId(int sessionId) {
        mFlags |= FLAG_HAS_SESSION;
        mSessionId = sessionId;
    }

    /** @hide */
    public void resetSessionId() {
        mFlags &= ~FLAG_HAS_SESSION;
        mSessionId = NO_SESSION;
    }

    /////////////////////////////////
    //  Object "contract" methods. //
    /////////////////////////////////

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + mViewId;
        result = prime * result + mVirtualIntId;
        result = prime * result + (int) (mVirtualLongId ^ (mVirtualLongId >>> 32));
        result = prime * result + mSessionId;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final AutofillId other = (AutofillId) obj;
        if (mViewId != other.mViewId) return false;
        if (mVirtualIntId != other.mVirtualIntId) return false;
        if (mVirtualLongId != other.mVirtualLongId) return false;
        if (mSessionId != other.mSessionId) return false;
        return true;
    }

    /** @hide */
    @TestApi
    public boolean equalsIgnoreSession(@Nullable AutofillId other) {
        if (this == other) return true;
        if (other == null) return false;
        if (mViewId != other.mViewId) return false;
        if (mVirtualIntId != other.mVirtualIntId) return false;
        if (mVirtualLongId != other.mVirtualLongId) return false;
        return true;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder().append(mViewId);
        if (isVirtualInt()) {
            builder.append(':').append(mVirtualIntId);
        } else if (isVirtualLong()) {
            builder.append(':').append(mVirtualLongId);
        }

        if (hasSession()) {
            builder.append('@').append(mSessionId);
        }
        return builder.toString();
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mViewId);
        parcel.writeInt(mFlags);
        if (hasSession()) {
            parcel.writeInt(mSessionId);
        }
        if (isVirtualInt()) {
            parcel.writeInt(mVirtualIntId);
        } else if (isVirtualLong()) {
            parcel.writeLong(mVirtualLongId);
        }
    }

    public static final @android.annotation.NonNull Parcelable.Creator<AutofillId> CREATOR =
            new Parcelable.Creator<AutofillId>() {
        @Override
        public AutofillId createFromParcel(Parcel source) {
            final int viewId = source.readInt();
            final int flags = source.readInt();
            final int sessionId = (flags & FLAG_HAS_SESSION) != 0 ? source.readInt() : NO_SESSION;
            if ((flags & FLAG_IS_VIRTUAL_INT) != 0) {
                return new AutofillId(flags, viewId, source.readInt(), sessionId);
            }
            if ((flags & FLAG_IS_VIRTUAL_LONG) != 0) {
                return new AutofillId(flags, viewId, source.readLong(), sessionId);
            }
            return new AutofillId(flags, viewId, View.NO_ID, sessionId);
        }

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