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

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.controls.actions.ControlAction;
import android.service.controls.templates.ControlTemplate;
import android.service.controls.templates.ControlTemplateWrapper;
import android.util.Log;

import com.android.internal.util.Preconditions;

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

/**
 * Represents a physical object that can be represented by a {@link ControlTemplate} and whose
 * properties may be modified through a {@link ControlAction}.
 *
 * The information is provided by a {@link ControlsProviderService} and represents static
 * information (not current status) about the device.
 * <p>
 * Each control needs a unique (per provider) identifier that is persistent across reboots of the
 * system.
 * <p>
 * Each {@link Control} will have a name, a subtitle and will optionally belong to a structure
 * and zone. Some of these values are defined by the user and/or the {@link ControlsProviderService}
 * and will be used to display the control as well as group them for management.
 * <p>
 * Each object will have an associated {@link DeviceTypes.DeviceType}. This will determine the icons and colors
 * used to display it.
 * <p>
 * An {@link Intent} linking to the provider Activity that expands on this {@link Control} and
 * allows for further actions should be provided.
 */
public final class Control implements Parcelable {
    private static final String TAG = "Control";

    private static final int NUM_STATUS = 5;
    /**
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            STATUS_UNKNOWN,
            STATUS_OK,
            STATUS_NOT_FOUND,
            STATUS_ERROR,
            STATUS_DISABLED,
    })
    public @interface Status {};

    public static final int STATUS_UNKNOWN = 0;

    /**
     * The device corresponding to the {@link Control} is responding correctly.
     */
    public static final int STATUS_OK = 1;

    /**
     * The device corresponding to the {@link Control} cannot be found or was removed.
     */
    public static final int STATUS_NOT_FOUND = 2;

    /**
     * The device corresponding to the {@link Control} is in an error state.
     */
    public static final int STATUS_ERROR = 3;

    /**
     * The {@link Control} is currently disabled.
     */
    public static final int STATUS_DISABLED = 4;

    private final @NonNull String mControlId;
    private final @DeviceTypes.DeviceType int mDeviceType;
    private final @NonNull CharSequence mTitle;
    private final @NonNull CharSequence mSubtitle;
    private final @Nullable CharSequence mStructure;
    private final @Nullable CharSequence mZone;
    private final @NonNull PendingIntent mAppIntent;

    private final @Nullable Icon mCustomIcon;
    private final @Nullable ColorStateList mCustomColor;

    private final @Status int mStatus;
    private final @NonNull ControlTemplate mControlTemplate;
    private final @NonNull CharSequence mStatusText;

    /**
     * @param controlId the unique persistent identifier for this object.
     * @param deviceType the type of device for this control. This will determine icons and colors.
     * @param title the user facing name of this control (e.g. "Bedroom thermostat").
     * @param subtitle a user facing subtitle with extra information about this control
     * @param structure a user facing name for the structure containing the device associated with
     *                  this control.
     * @param zone
     * @param appIntent a {@link PendingIntent} linking to a page to interact with the
     *                  corresponding device.
     * @param customIcon
     * @param customColor
     * @param status
     * @param controlTemplate
     * @param statusText
     */
    Control(@NonNull String controlId,
            @DeviceTypes.DeviceType int deviceType,
            @NonNull CharSequence title,
            @NonNull CharSequence subtitle,
            @Nullable CharSequence structure,
            @Nullable CharSequence zone,
            @NonNull PendingIntent appIntent,
            @Nullable Icon customIcon,
            @Nullable ColorStateList customColor,
            @Status int status,
            @NonNull ControlTemplate controlTemplate,
            @NonNull CharSequence statusText) {
        Preconditions.checkNotNull(controlId);
        Preconditions.checkNotNull(title);
        Preconditions.checkNotNull(subtitle);
        Preconditions.checkNotNull(appIntent);
        Preconditions.checkNotNull(controlTemplate);
        Preconditions.checkNotNull(statusText);
        mControlId = controlId;
        if (!DeviceTypes.validDeviceType(deviceType)) {
            Log.e(TAG, "Invalid device type:" + deviceType);
            mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        } else {
            mDeviceType = deviceType;
        }
        mTitle = title;
        mSubtitle = subtitle;
        mStructure = structure;
        mZone = zone;
        mAppIntent = appIntent;

        mCustomColor = customColor;
        mCustomIcon = customIcon;

        if (status < 0 || status >= NUM_STATUS) {
            mStatus = STATUS_UNKNOWN;
            Log.e(TAG, "Status unknown:" + status);
        } else {
            mStatus = status;
        }
        mControlTemplate = controlTemplate;
        mStatusText = statusText;
    }

    /**
     * @param in
     * @hide
     */
    Control(Parcel in) {
        mControlId = in.readString();
        mDeviceType = in.readInt();
        mTitle = in.readCharSequence();
        mSubtitle = in.readCharSequence();
        if (in.readByte() == (byte) 1) {
            mStructure = in.readCharSequence();
        } else {
            mStructure = null;
        }
        if (in.readByte() == (byte) 1) {
            mZone = in.readCharSequence();
        } else {
            mZone = null;
        }
        mAppIntent = PendingIntent.CREATOR.createFromParcel(in);

        if (in.readByte() == (byte) 1) {
            mCustomIcon = Icon.CREATOR.createFromParcel(in);
        } else {
            mCustomIcon = null;
        }

        if (in.readByte() == (byte) 1) {
            mCustomColor = ColorStateList.CREATOR.createFromParcel(in);
        } else {
            mCustomColor = null;
        }

        mStatus = in.readInt();
        ControlTemplateWrapper wrapper = ControlTemplateWrapper.CREATOR.createFromParcel(in);
        mControlTemplate = wrapper.getWrappedTemplate();
        mStatusText = in.readCharSequence();
    }

    /**
     * @return the identifier for the {@link Control}
     */
    @NonNull
    public String getControlId() {
        return mControlId;
    }


    /**
     * @return type of device represented by this {@link Control}, used to determine the default
     *         icon and color
     */
    @DeviceTypes.DeviceType
    public int getDeviceType() {
        return mDeviceType;
    }

    /**
     * @return the user facing name of the {@link Control}
     */
    @NonNull
    public CharSequence getTitle() {
        return mTitle;
    }

    /**
     * @return additional information about the {@link Control}, to appear underneath the title
     */
    @NonNull
    public CharSequence getSubtitle() {
        return mSubtitle;
    }

    /**
     * Optional top-level group to help define the {@link Control}'s location, visible to the user.
     * If not present, the application name will be used as the top-level group. A structure
     * contains zones which contains controls.
     *
     * @return name of the structure containing the control
     */
    @Nullable
    public CharSequence getStructure() {
        return mStructure;
    }

    /**
     * Optional group name to help define the {@link Control}'s location within a structure,
     * visible to the user. A structure contains zones which contains controls.
     *
     * @return name of the zone containing the control
     */
    @Nullable
    public CharSequence getZone() {
        return mZone;
    }

    /**
     * @return a {@link PendingIntent} linking to an Activity for the {@link Control}
     */
    @NonNull
    public PendingIntent getAppIntent() {
        return mAppIntent;
    }

    /**
     * Optional icon to be shown with the {@link Control}. It is highly recommended
     * to let the system default the icon unless the default icon is not suitable.
     *
     * @return icon to show
     */
    @Nullable
    public Icon getCustomIcon() {
        return mCustomIcon;
    }

    /**
     * Optional color to be shown with the {@link Control}. It is highly recommended
     * to let the system default the color unless the default is not suitable for the
     * application.
     *
     * @return background color to use
     */
    @Nullable
    public ColorStateList getCustomColor() {
        return mCustomColor;
    }

    /**
     * @return status of the {@link Control}, used to convey information about the attempt to
     *         fetch the current state
     */
    @Status
    public int getStatus() {
        return mStatus;
    }

    /**
     * @return instance of {@link ControlTemplate}, that defines how the {@link Control} will
     *         behave and what interactions are available to the user
     */
    @NonNull
    public ControlTemplate getControlTemplate() {
        return mControlTemplate;
    }

    /**
     * @return user-facing text description of the {@link Control}'s status, describing its current
     *         state
     */
    @NonNull
    public CharSequence getStatusText() {
        return mStatusText;
    }

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

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(mControlId);
        dest.writeInt(mDeviceType);
        dest.writeCharSequence(mTitle);
        dest.writeCharSequence(mSubtitle);
        if (mStructure != null) {
            dest.writeByte((byte) 1);
            dest.writeCharSequence(mStructure);
        } else {
            dest.writeByte((byte) 0);
        }
        if (mZone != null) {
            dest.writeByte((byte) 1);
            dest.writeCharSequence(mZone);
        } else {
            dest.writeByte((byte) 0);
        }
        mAppIntent.writeToParcel(dest, flags);
        if (mCustomIcon != null) {
            dest.writeByte((byte) 1);
            mCustomIcon.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }
        if (mCustomColor != null) {
            dest.writeByte((byte) 1);
            mCustomColor.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }

        dest.writeInt(mStatus);
        new ControlTemplateWrapper(mControlTemplate).writeToParcel(dest, flags);
        dest.writeCharSequence(mStatusText);
    }

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

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

    /**
     * Builder class for {@link Control}.
     *
     * This class facilitates the creation of {@link Control} with no state. Must be used to
     * provide controls for {@link ControlsProviderService#createPublisherForAllAvailable} and
     * {@link ControlsProviderService#createPublisherForSuggested}.
     *
     * It provides the following defaults for non-optional parameters:
     * <ul>
     *     <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN}
     *     <li> Title: {@code ""}
     *     <li> Subtitle: {@code ""}
     * </ul>
     * This fixes the values relating to state of the {@link Control} as required by
     * {@link ControlsProviderService#createPublisherForAllAvailable}:
     * <ul>
     *     <li> Status: {@link Status#STATUS_UNKNOWN}
     *     <li> Control template: {@link ControlTemplate#getNoTemplateObject}
     *     <li> Status text: {@code ""}
     * </ul>
     */
    @SuppressLint("MutableBareField")
    public static final class StatelessBuilder {
        private static final String TAG = "StatelessBuilder";
        private @NonNull String mControlId;
        private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        private @NonNull CharSequence mTitle = "";
        private @NonNull CharSequence mSubtitle = "";
        private @Nullable CharSequence mStructure;
        private @Nullable CharSequence mZone;
        private @NonNull PendingIntent mAppIntent;
        private @Nullable Icon mCustomIcon;
        private @Nullable ColorStateList mCustomColor;

        /**
         * @param controlId the identifier for the {@link Control}
         * @param appIntent the pending intent linking to the device Activity
         */
        public StatelessBuilder(@NonNull String controlId,
                @NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(controlId);
            Preconditions.checkNotNull(appIntent);
            mControlId = controlId;
            mAppIntent = appIntent;
        }

        /**
         * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base.
         *
         * @param control base for the builder.
         */
        public StatelessBuilder(@NonNull Control control) {
            Preconditions.checkNotNull(control);
            mControlId = control.mControlId;
            mDeviceType = control.mDeviceType;
            mTitle = control.mTitle;
            mSubtitle = control.mSubtitle;
            mStructure = control.mStructure;
            mZone = control.mZone;
            mAppIntent = control.mAppIntent;
            mCustomIcon = control.mCustomIcon;
            mCustomColor = control.mCustomColor;
        }

        /**
         * @param controlId the identifier for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setControlId(@NonNull String controlId) {
            Preconditions.checkNotNull(controlId);
            mControlId = controlId;
            return this;
        }

        /**
         * @param deviceType type of device represented by this {@link Control}, used to
         *                   determine the default icon and color
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
            if (!DeviceTypes.validDeviceType(deviceType)) {
                Log.e(TAG, "Invalid device type:" + deviceType);
                mDeviceType = DeviceTypes.TYPE_UNKNOWN;
            } else {
                mDeviceType = deviceType;
            }
            return this;
        }

        /**
         * @param title the user facing name of the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setTitle(@NonNull CharSequence title) {
            Preconditions.checkNotNull(title);
            mTitle = title;
            return this;
        }

        /**
         * @param subtitle additional information about the {@link Control}, to appear underneath
         *                 the title
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setSubtitle(@NonNull CharSequence subtitle) {
            Preconditions.checkNotNull(subtitle);
            mSubtitle = subtitle;
            return this;
        }

        /**
         * Optional top-level group to help define the {@link Control}'s location, visible to the
         * user. If not present, the application name will be used as the top-level group. A
         * structure contains zones which contains controls.
         *
         * @param structure name of the structure containing the control
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setStructure(@Nullable CharSequence structure) {
            mStructure = structure;
            return this;
        }

        /**
         * Optional group name to help define the {@link Control}'s location within a structure,
         * visible to the user. A structure contains zones which contains controls.
         *
         * @param zone name of the zone containing the control
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setZone(@Nullable CharSequence zone) {
            mZone = zone;
            return this;
        }

        /**
         * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setAppIntent(@NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(appIntent);
            mAppIntent = appIntent;
            return this;
        }

        /**
         * Optional icon to be shown with the {@link Control}. It is highly recommended
         * to let the system default the icon unless the default icon is not suitable.
         *
         * @param customIcon icon to show
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setCustomIcon(@Nullable Icon customIcon) {
            mCustomIcon = customIcon;
            return this;
        }

        /**
         * Optional color to be shown with the {@link Control}. It is highly recommended
         * to let the system default the color unless the default is not suitable for the
         * application.
         *
         * @param customColor background color to use
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setCustomColor(@Nullable ColorStateList customColor) {
            mCustomColor = customColor;
            return this;
        }

        /**
         * @return a valid {@link Control}
         */
        @NonNull
        public Control build() {
            return new Control(mControlId,
                    mDeviceType,
                    mTitle,
                    mSubtitle,
                    mStructure,
                    mZone,
                    mAppIntent,
                    mCustomIcon,
                    mCustomColor,
                    STATUS_UNKNOWN,
                    ControlTemplate.NO_TEMPLATE,
                    "");
        }
    }

    /**
     * Builder class for {@link Control} that contains state information.
     *
     * State information is passed through an instance of a {@link ControlTemplate} and will
     * determine how the user can interact with the {@link Control}. User interactions will
     * be sent through the method call {@link ControlsProviderService#performControlAction}
     * with an instance of {@link ControlAction} to convey any potential new value.
     *
     * Must be used to provide controls for {@link ControlsProviderService#createPublisherFor}.
     *
     * It provides the following defaults for non-optional parameters:
     * <ul>
     *     <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN}
     *     <li> Title: {@code ""}
     *     <li> Subtitle: {@code ""}
     *     <li> Status: {@link Status#STATUS_UNKNOWN}
     *     <li> Control template: {@link ControlTemplate#getNoTemplateObject}
     *     <li> Status text: {@code ""}
     * </ul>
     */
    public static final class StatefulBuilder {
        private static final String TAG = "StatefulBuilder";
        private @NonNull String mControlId;
        private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        private @NonNull CharSequence mTitle = "";
        private @NonNull CharSequence mSubtitle = "";
        private @Nullable CharSequence mStructure;
        private @Nullable CharSequence mZone;
        private @NonNull PendingIntent mAppIntent;
        private @Nullable Icon mCustomIcon;
        private @Nullable ColorStateList mCustomColor;
        private @Status int mStatus = STATUS_UNKNOWN;
        private @NonNull ControlTemplate mControlTemplate = ControlTemplate.NO_TEMPLATE;
        private @NonNull CharSequence mStatusText = "";

        /**
         * @param controlId the identifier for the {@link Control}.
         * @param appIntent the pending intent linking to the device Activity.
         */
        public StatefulBuilder(@NonNull String controlId,
                @NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(controlId);
            Preconditions.checkNotNull(appIntent);
            mControlId = controlId;
            mAppIntent = appIntent;
        }

        /**
         * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base.
         *
         * @param control base for the builder.
         */
        public StatefulBuilder(@NonNull Control control) {
            Preconditions.checkNotNull(control);
            mControlId = control.mControlId;
            mDeviceType = control.mDeviceType;
            mTitle = control.mTitle;
            mSubtitle = control.mSubtitle;
            mStructure = control.mStructure;
            mZone = control.mZone;
            mAppIntent = control.mAppIntent;
            mCustomIcon = control.mCustomIcon;
            mCustomColor = control.mCustomColor;
            mStatus = control.mStatus;
            mControlTemplate = control.mControlTemplate;
            mStatusText = control.mStatusText;
        }

        /**
         * @param controlId the identifier for the {@link Control}.
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setControlId(@NonNull String controlId) {
            Preconditions.checkNotNull(controlId);
            mControlId = controlId;
            return this;
        }

        /**
         * @param deviceType type of device represented by this {@link Control}, used to
         *                   determine the default icon and color
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
            if (!DeviceTypes.validDeviceType(deviceType)) {
                Log.e(TAG, "Invalid device type:" + deviceType);
                mDeviceType = DeviceTypes.TYPE_UNKNOWN;
            } else {
                mDeviceType = deviceType;
            }
            return this;
        }

        /**
         * @param title the user facing name of the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setTitle(@NonNull CharSequence title) {
            Preconditions.checkNotNull(title);
            mTitle = title;
            return this;
        }

        /**
         * @param subtitle additional information about the {@link Control}, to appear underneath
         *                 the title
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setSubtitle(@NonNull CharSequence subtitle) {
            Preconditions.checkNotNull(subtitle);
            mSubtitle = subtitle;
            return this;
        }

        /**
         * Optional top-level group to help define the {@link Control}'s location, visible to the
         * user. If not present, the application name will be used as the top-level group. A
         * structure contains zones which contains controls.
         *
         * @param structure name of the structure containing the control
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStructure(@Nullable CharSequence structure) {
            mStructure = structure;
            return this;
        }

        /**
         * Optional group name to help define the {@link Control}'s location within a structure,
         * visible to the user. A structure contains zones which contains controls.
         *
         * @param zone name of the zone containing the control
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setZone(@Nullable CharSequence zone) {
            mZone = zone;
            return this;
        }

        /**
         * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setAppIntent(@NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(appIntent);
            mAppIntent = appIntent;
            return this;
        }

        /**
         * Optional icon to be shown with the {@link Control}. It is highly recommended
         * to let the system default the icon unless the default icon is not suitable.
         *
         * @param customIcon icon to show
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setCustomIcon(@Nullable Icon customIcon) {
            mCustomIcon = customIcon;
            return this;
        }

        /**
         * Optional color to be shown with the {@link Control}. It is highly recommended
         * to let the system default the color unless the default is not suitable for the
         * application.
         *
         * @param customColor background color to use
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setCustomColor(@Nullable ColorStateList customColor) {
            mCustomColor = customColor;
            return this;
        }

        /**
         * @param status status of the {@link Control}, used to convey information about the
         *               attempt to fetch the current state
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStatus(@Status int status) {
            if (status < 0 || status >= NUM_STATUS) {
                mStatus = STATUS_UNKNOWN;
                Log.e(TAG, "Status unknown:" + status);
            } else {
                mStatus = status;
            }
            return this;
        }

        /**
         * @param controlTemplate instance of {@link ControlTemplate}, that defines how the
         *                        {@link Control} will behave and what interactions are
         *                        available to the user
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setControlTemplate(@NonNull ControlTemplate controlTemplate) {
            Preconditions.checkNotNull(controlTemplate);
            mControlTemplate = controlTemplate;
            return this;
        }

        /**
         * @param statusText user-facing text description of the {@link Control}'s status,
         *                   describing its current state
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStatusText(@NonNull CharSequence statusText) {
            Preconditions.checkNotNull(statusText);
            mStatusText = statusText;
            return this;
        }

        /**
         * @return a valid {@link Control}
         */
        @NonNull
        public Control build() {
            return new Control(mControlId,
                    mDeviceType,
                    mTitle,
                    mSubtitle,
                    mStructure,
                    mZone,
                    mAppIntent,
                    mCustomIcon,
                    mCustomColor,
                    mStatus,
                    mControlTemplate,
                    mStatusText);
        }
    }
}
