/*
 * Copyright (C) 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.window;

import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WindowingMode;
import static android.view.Display.DEFAULT_DISPLAY;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.DataClass;

import java.util.Objects;

/**
 * Data object for options to create Task with.
 * @see TaskOrganizer#createTask(TaskCreationParams)
 * @hide
 */
@TestApi
@DataClass(genEqualsHashCode = true, genParcelable = true, genToString = true, genBuilder = true)
public final class TaskCreationParams implements Parcelable {

    /** The Task name. */
    @Nullable
    private String mName = null;

    /**
     * The display to launch the Task in.
     * Note: the Task creation will fail if the display doesn't exist.
     */
    private int mDisplayId = DEFAULT_DISPLAY;

    /**
     * The requested parent window to launch the Task in.
     * When this is {@code null}, the Task will by default be launched into
     * the default TaskDisplayArea of the {@link #getDisplayId()}.
     * Note: the Task creation will fail if any of the following is met:
     *  - The requested parent window doesn't exist.
     *  - The requested parent window is not a valid Task or TaskDisplayArea.
     *  - The requested parent window is not in the {@link #getDisplayId()}.
     *
     * @hide
     */
    @Nullable
    private WindowContainerToken mParentContainer = null;

    /** The requested {@link WindowingMode}. */
    @WindowingMode
    private int mWindowingMode = WINDOWING_MODE_UNDEFINED;

    /**
     * Whether this Task should serve as a visibility barrier, which is an empty Task
     * that should occlude siblings below it.
     * This is different from {@link TaskPropertiesRequest#isForceOpaque} that a visibility
     * barrier should remain empty, and will throw {@link IllegalStateException} if trying
     * to add a child window to it.
     * When this is {@code true}, {@link #getWindowingMode()} and most of the
     * {@link #getTaskPropertiesRequest()} are ignored.
     *
     * Note: the visibility barrier itself is not opaque because it doesn't contain any
     * content. As a result, if it is above all other opaque siblings, the parent container
     * will not be opaque either because there is no more visible opaque contents in it.
     *
     * @hide
     */
    private boolean mVisibilityBarrier = false;

    /**
     * The unique launch cookie associated with the new Task, which can be used to identify
     * the Task from {@link android.app.TaskInfo#containsLaunchCookie}.
     */
    @NonNull
    private IBinder mLaunchCookie = new Binder();

    /**
     * The initial {@link TaskPropertiesRequest}.
     * @hide
     */
    @NonNull
    private TaskPropertiesRequest mTaskPropertiesRequest = new TaskPropertiesRequest();

    // TODO(b/468029217) uncomment and remove setLaunchCookie after TaskOrganizer#createRootTask is
    //  removed from @TestApi.
    // Suppress setter generation for mLaunchCookie that is not supposed to come from user input.
    // @DataClass.Suppress("setLaunchCookie")
    static abstract class BaseBuilder {
        /**
         * @hide
         */
        abstract Builder setLaunchCookie(@NonNull IBinder value);
    }



    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/window/TaskCreationParams.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    @DataClass.Generated.Member
    /* package-private */ TaskCreationParams(
            @Nullable String name,
            int displayId,
            @Nullable WindowContainerToken parentContainer,
            @WindowingMode int windowingMode,
            boolean visibilityBarrier,
            @NonNull IBinder launchCookie,
            @NonNull TaskPropertiesRequest taskPropertiesRequest) {
        this.mName = name;
        this.mDisplayId = displayId;
        this.mParentContainer = parentContainer;
        this.mWindowingMode = windowingMode;
        com.android.internal.util.AnnotationValidations.validate(
                WindowingMode.class, null, mWindowingMode);
        this.mVisibilityBarrier = visibilityBarrier;
        this.mLaunchCookie = launchCookie;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mLaunchCookie);
        this.mTaskPropertiesRequest = taskPropertiesRequest;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mTaskPropertiesRequest);

        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * The Task name.
     */
    @DataClass.Generated.Member
    public @Nullable String getName() {
        return mName;
    }

    /**
     * The display to launch the Task in.
     * Note: the Task creation will fail if the display doesn't exist.
     */
    @DataClass.Generated.Member
    public int getDisplayId() {
        return mDisplayId;
    }

    /**
     * The requested parent window to launch the Task in.
     * When this is {@code null}, the Task will by default be launched into
     * the default TaskDisplayArea of the {@link #getDisplayId()}.
     * Note: the Task creation will fail if any of the following is met:
     *  - The requested parent window doesn't exist.
     *  - The requested parent window is not a valid Task or TaskDisplayArea.
     *  - The requested parent window is not in the {@link #getDisplayId()}.
     *
     * @hide
     */
    @DataClass.Generated.Member
    public @Nullable WindowContainerToken getParentContainer() {
        return mParentContainer;
    }

    /**
     * The requested {@link WindowingMode}.
     */
    @DataClass.Generated.Member
    public @WindowingMode int getWindowingMode() {
        return mWindowingMode;
    }

    /**
     * Whether this Task should serve as a visibility barrier, which is an empty Task
     * that should occlude siblings below it.
     * This is different from {@link TaskPropertiesRequest#isForceOpaque} that a visibility
     * barrier should remain empty, and will throw {@link IllegalStateException} if trying
     * to add a child window to it.
     * When this is {@code true}, {@link #getWindowingMode()} and most of the
     * {@link #getTaskPropertiesRequest()} are ignored.
     *
     * Note: the visibility barrier itself is not opaque because it doesn't contain any
     * content. As a result, if it is above all other opaque siblings, the parent container
     * will not be opaque either because there is no more visible opaque contents in it.
     *
     * @hide
     */
    @DataClass.Generated.Member
    public boolean isVisibilityBarrier() {
        return mVisibilityBarrier;
    }

    /**
     * The unique launch cookie associated with the new Task, which can be used to identify
     * the Task from {@link android.app.TaskInfo#containsLaunchCookie}.
     */
    @DataClass.Generated.Member
    public @NonNull IBinder getLaunchCookie() {
        return mLaunchCookie;
    }

    /**
     * The initial {@link TaskPropertiesRequest}.
     *
     * @hide
     */
    @DataClass.Generated.Member
    public @NonNull TaskPropertiesRequest getTaskPropertiesRequest() {
        return mTaskPropertiesRequest;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
        // You can override field toString logic by defining methods like:
        // String fieldNameToString() { ... }

        return "TaskCreationParams { " +
                "name = " + mName + ", " +
                "displayId = " + mDisplayId + ", " +
                "parentContainer = " + mParentContainer + ", " +
                "windowingMode = " + mWindowingMode + ", " +
                "visibilityBarrier = " + mVisibilityBarrier + ", " +
                "launchCookie = " + mLaunchCookie + ", " +
                "taskPropertiesRequest = " + mTaskPropertiesRequest +
        " }";
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@Nullable Object o) {
        // You can override field equality logic by defining either of the methods like:
        // boolean fieldNameEquals(TaskCreationParams other) { ... }
        // boolean fieldNameEquals(FieldType otherValue) { ... }

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        TaskCreationParams that = (TaskCreationParams) o;
        //noinspection PointlessBooleanExpression
        return true
                && Objects.equals(mName, that.mName)
                && mDisplayId == that.mDisplayId
                && Objects.equals(mParentContainer, that.mParentContainer)
                && mWindowingMode == that.mWindowingMode
                && mVisibilityBarrier == that.mVisibilityBarrier
                && Objects.equals(mLaunchCookie, that.mLaunchCookie)
                && Objects.equals(mTaskPropertiesRequest, that.mTaskPropertiesRequest);
    }

    @Override
    @DataClass.Generated.Member
    public int hashCode() {
        // You can override field hashCode logic by defining methods like:
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + Objects.hashCode(mName);
        _hash = 31 * _hash + mDisplayId;
        _hash = 31 * _hash + Objects.hashCode(mParentContainer);
        _hash = 31 * _hash + mWindowingMode;
        _hash = 31 * _hash + Boolean.hashCode(mVisibilityBarrier);
        _hash = 31 * _hash + Objects.hashCode(mLaunchCookie);
        _hash = 31 * _hash + Objects.hashCode(mTaskPropertiesRequest);
        return _hash;
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        byte flg = 0;
        if (mVisibilityBarrier) flg |= 0x10;
        if (mName != null) flg |= 0x1;
        if (mParentContainer != null) flg |= 0x4;
        dest.writeByte(flg);
        if (mName != null) dest.writeString(mName);
        dest.writeInt(mDisplayId);
        if (mParentContainer != null) dest.writeTypedObject(mParentContainer, flags);
        dest.writeInt(mWindowingMode);
        dest.writeStrongBinder(mLaunchCookie);
        dest.writeTypedObject(mTaskPropertiesRequest, flags);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ TaskCreationParams(@NonNull Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte flg = in.readByte();
        boolean visibilityBarrier = (flg & 0x10) != 0;
        String name = (flg & 0x1) == 0 ? null : in.readString();
        int displayId = in.readInt();
        WindowContainerToken parentContainer = (flg & 0x4) == 0 ? null : (WindowContainerToken) in.readTypedObject(WindowContainerToken.CREATOR);
        int windowingMode = in.readInt();
        IBinder launchCookie = (IBinder) in.readStrongBinder();
        TaskPropertiesRequest taskPropertiesRequest = (TaskPropertiesRequest) in.readTypedObject(TaskPropertiesRequest.CREATOR);

        this.mName = name;
        this.mDisplayId = displayId;
        this.mParentContainer = parentContainer;
        this.mWindowingMode = windowingMode;
        com.android.internal.util.AnnotationValidations.validate(
                WindowingMode.class, null, mWindowingMode);
        this.mVisibilityBarrier = visibilityBarrier;
        this.mLaunchCookie = launchCookie;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mLaunchCookie);
        this.mTaskPropertiesRequest = taskPropertiesRequest;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mTaskPropertiesRequest);

        // onConstructed(); // You can define this method to get a callback
    }

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

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

    /**
     * A builder for {@link TaskCreationParams}
     */
    @SuppressWarnings("WeakerAccess")
    @DataClass.Generated.Member
    public static final class Builder extends BaseBuilder {

        private @Nullable String mName;
        private int mDisplayId;
        private @Nullable WindowContainerToken mParentContainer;
        private @WindowingMode int mWindowingMode;
        private boolean mVisibilityBarrier;
        private @NonNull IBinder mLaunchCookie;
        private @NonNull TaskPropertiesRequest mTaskPropertiesRequest;

        private long mBuilderFieldsSet = 0L;

        public Builder() {
        }

        /**
         * The Task name.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setName(@NonNull String value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x1;
            mName = value;
            return this;
        }

        /**
         * The display to launch the Task in.
         * Note: the Task creation will fail if the display doesn't exist.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setDisplayId(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x2;
            mDisplayId = value;
            return this;
        }

        /**
         * The requested parent window to launch the Task in.
         * When this is {@code null}, the Task will by default be launched into
         * the default TaskDisplayArea of the {@link #getDisplayId()}.
         * Note: the Task creation will fail if any of the following is met:
         *  - The requested parent window doesn't exist.
         *  - The requested parent window is not a valid Task or TaskDisplayArea.
         *  - The requested parent window is not in the {@link #getDisplayId()}.
         *
         * @hide
         */
        @DataClass.Generated.Member
        public @NonNull Builder setParentContainer(@NonNull WindowContainerToken value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x4;
            mParentContainer = value;
            return this;
        }

        /**
         * The requested {@link WindowingMode}.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setWindowingMode(@WindowingMode int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x8;
            mWindowingMode = value;
            return this;
        }

        /**
         * Whether this Task should serve as a visibility barrier, which is an empty Task
         * that should occlude siblings below it.
         * This is different from {@link TaskPropertiesRequest#isForceOpaque} that a visibility
         * barrier should remain empty, and will throw {@link IllegalStateException} if trying
         * to add a child window to it.
         * When this is {@code true}, {@link #getWindowingMode()} and most of the
         * {@link #getTaskPropertiesRequest()} are ignored.
         *
         * Note: the visibility barrier itself is not opaque because it doesn't contain any
         * content. As a result, if it is above all other opaque siblings, the parent container
         * will not be opaque either because there is no more visible opaque contents in it.
         *
         * @hide
         */
        @DataClass.Generated.Member
        public @NonNull Builder setVisibilityBarrier(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x10;
            mVisibilityBarrier = value;
            return this;
        }

        /**
         * The unique launch cookie associated with the new Task, which can be used to identify
         * the Task from {@link android.app.TaskInfo#containsLaunchCookie}.
         */
        @DataClass.Generated.Member
        @Override
        @NonNull Builder setLaunchCookie(@NonNull IBinder value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x20;
            mLaunchCookie = value;
            return this;
        }

        /**
         * The initial {@link TaskPropertiesRequest}.
         *
         * @hide
         */
        @DataClass.Generated.Member
        public @NonNull Builder setTaskPropertiesRequest(@NonNull TaskPropertiesRequest value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x40;
            mTaskPropertiesRequest = value;
            return this;
        }

        /** Builds the instance. This builder should not be touched after calling this! */
        public @NonNull TaskCreationParams build() {
            checkNotUsed();
            mBuilderFieldsSet |= 0x80; // Mark builder used

            if ((mBuilderFieldsSet & 0x1) == 0) {
                mName = null;
            }
            if ((mBuilderFieldsSet & 0x2) == 0) {
                mDisplayId = DEFAULT_DISPLAY;
            }
            if ((mBuilderFieldsSet & 0x4) == 0) {
                mParentContainer = null;
            }
            if ((mBuilderFieldsSet & 0x8) == 0) {
                mWindowingMode = WINDOWING_MODE_UNDEFINED;
            }
            if ((mBuilderFieldsSet & 0x10) == 0) {
                mVisibilityBarrier = false;
            }
            if ((mBuilderFieldsSet & 0x20) == 0) {
                mLaunchCookie = new Binder();
            }
            if ((mBuilderFieldsSet & 0x40) == 0) {
                mTaskPropertiesRequest = new TaskPropertiesRequest();
            }
            TaskCreationParams o = new TaskCreationParams(
                    mName,
                    mDisplayId,
                    mParentContainer,
                    mWindowingMode,
                    mVisibilityBarrier,
                    mLaunchCookie,
                    mTaskPropertiesRequest);
            return o;
        }

        private void checkNotUsed() {
            if ((mBuilderFieldsSet & 0x80) != 0) {
                throw new IllegalStateException(
                        "This Builder should not be reused. Use a new Builder instance instead");
            }
        }
    }

    @DataClass.Generated(
            time = 1767928981582L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/window/TaskCreationParams.java",
            inputSignatures = "private @android.annotation.Nullable java.lang.String mName\nprivate  int mDisplayId\nprivate @android.annotation.Nullable android.window.WindowContainerToken mParentContainer\nprivate @android.app.WindowConfiguration.WindowingMode int mWindowingMode\nprivate  boolean mVisibilityBarrier\nprivate @android.annotation.NonNull android.os.IBinder mLaunchCookie\nprivate @android.annotation.NonNull android.window.TaskPropertiesRequest mTaskPropertiesRequest\nclass TaskCreationParams extends java.lang.Object implements [android.os.Parcelable]\nabstract  android.window.TaskCreationParams.Builder setLaunchCookie(android.os.IBinder)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genParcelable=true, genToString=true, genBuilder=true)\nabstract  android.window.TaskCreationParams.Builder setLaunchCookie(android.os.IBinder)\nclass BaseBuilder extends java.lang.Object implements []")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
