/*
 * Copyright 2025 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.media.tv.interactive;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

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

/**
 * Information about a web service client.
 * @hide
 */
public class WebServiceClientInfo implements Parcelable {
    @IntDef(prefix = "WEB_SERVICE_CLIENT_STATE_", value = {
            WEB_SERVICE_CLIENT_STATE_UNDEFINED,
            WEB_SERVICE_CLIENT_STATE_TRUSTED,
            WEB_SERVICE_CLIENT_STATE_UNTRUSTED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface WebServiceClientState {}

    public static final int WEB_SERVICE_CLIENT_STATE_UNDEFINED = 0;
    public static final int WEB_SERVICE_CLIENT_STATE_TRUSTED = 1;
    public static final int WEB_SERVICE_CLIENT_STATE_UNTRUSTED = 2;

    private final int mHandle;
    private final @WebServiceClientState int mClientState;
    @NonNull
    private final String mUuid;
    @NonNull
    private final String mName;
    @Nullable
    private final Bundle mExtra;

    /**
     * Creates a new WebServiceClient.
     *
     * @param handle handle id for the web service client, assigned by TIAS.
     * @param clientState client state, must be one of {@link WebServiceClientState}.
     * @param uuid uuid of the web service client, generated by the web service client.
     * @param name name of the web service client.
     */
    public WebServiceClientInfo(
            int handle,
            @WebServiceClientState int clientState,
            @NonNull String uuid,
            @NonNull String name,
            @Nullable Bundle extra) {
        mHandle = handle;
        mClientState = clientState;
        mUuid = uuid;
        mName = name;
        mExtra = extra;
    }

    /**
     * Returns the transient handle ID assigned by TIAS to identify this web service client.
     * * NOTE: This is a volatile integer scoped to the current TIAS session. Active communication
     * must use this handle id instead of the {@link #getUuid()} to optimize backend performance
     * and maintain a clean session state.
     * @return handle id.
     */
    public int getHandle() {
        return mHandle;
    }

    /**
     * Returns the client state.
     * @return client state, must be one of {@link WebServiceClientState}.
     */
    public @WebServiceClientState int getClientState() {
        return mClientState;
    }

    /**
     * Returns the Universally Unique Identifier (UUID) for this web service client instance.
     * Unlike the session handle, this is a persistent String that remains constant across
     * TIAS sessions. UUID should not be used for active communication and should only be used for
     * data persistence.
     */
    @NonNull
    public String getUuid() {
        return mUuid;
    }

    /**
     * returns the name.
     */
    @NonNull
    public String getName() {
        return mName;
    }

    /**
     * Returns the extra bundle. May be null.
     */
    @Nullable
    public Bundle getExtra() {
        return mExtra;
    }

    @Override
    public String toString() {
        return "WebServiceClientInfo {"
                + "handle=" + mHandle
                + ", clientState=" + mClientState
                + ", uuid='" + mUuid + '\''
                + ", name='" + mName + '\''
                + ", extra=" + (mExtra != null ? mExtra.toString() : "null")
                + '}';
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mHandle);
        dest.writeInt(mClientState);
        dest.writeString(mUuid);
        dest.writeString8(mName);
        dest.writeBundle(mExtra);
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(mHandle, mClientState, mUuid, mName, mExtra);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof WebServiceClientInfo)) return false;
        WebServiceClientInfo that = (WebServiceClientInfo) o;
        return mHandle == that.mHandle
                && mClientState == that.mClientState
                && mUuid.equals(that.mUuid)
                && mName.equals(that.mName)
                && Objects.equals(mExtra, that.mExtra);
    }

    /* package-private */ WebServiceClientInfo(@NonNull Parcel in) {
        mHandle = in.readInt();
        mClientState = in.readInt();
        String uuid = in.readString();
        mUuid = uuid != null ? uuid : "";
        String name = in.readString8();
        mName = name != null ? name : "";
        mExtra = in.readBundle(WebServiceClientInfo.class.getClassLoader());
    }

    @NonNull
    public static final Parcelable.Creator<WebServiceClientInfo> CREATOR =
            new Parcelable.Creator<WebServiceClientInfo>() {
                @Override
                public WebServiceClientInfo[] newArray(int size) {
                    return new WebServiceClientInfo[size];
                }

                @Override
                public WebServiceClientInfo createFromParcel(@NonNull Parcel in) {
                    return new WebServiceClientInfo(in);
                }
            };
}
