/**
 * Copyright (c) 2014, 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.notification;

import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

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

/**
 * The current condition of an {@link android.app.AutomaticZenRule}, provided by the
 * {@link ConditionProviderService} that owns the rule. Used to tell the system to enter Do Not
 * Disturb mode and request that the system exit Do Not Disturb mode.
 */
public final class Condition implements Parcelable {

    @SystemApi
    public static final String SCHEME = "condition";

    /** @hide */
    @IntDef(prefix = { "STATE_" }, value = {
            STATE_FALSE,
            STATE_TRUE,
            STATE_UNKNOWN,
            STATE_ERROR
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {}

    /**
     * Indicates that Do Not Disturb should be turned off. Note that all Conditions from all
     * {@link ConditionProviderService} providers must be off for Do Not Disturb to be turned off on
     * the device.
     */
    public static final int STATE_FALSE = 0;
    /**
     * Indicates that Do Not Disturb should be turned on.
     */
    public static final int STATE_TRUE = 1;

    @SystemApi
    public static final int STATE_UNKNOWN = 2;
    @SystemApi
    public static final int STATE_ERROR = 3;

    @SystemApi
    public static final int FLAG_RELEVANT_NOW = 1 << 0;
    @SystemApi
    public static final int FLAG_RELEVANT_ALWAYS = 1 << 1;

    /**
     * The URI representing the rule being updated.
     * See {@link android.app.AutomaticZenRule#getConditionId()}.
     */
    public final Uri id;

    /**
     * A summary of what the rule encoded in {@link #id} means when it is enabled. User visible
     * if the state of the condition is {@link #STATE_TRUE}.
     */
    public final String summary;

    @SystemApi
    public final String line1;
    @SystemApi
    public final String line2;

    /**
     * The state of this condition. {@link #STATE_TRUE} will enable Do Not Disturb mode.
     * {@link #STATE_FALSE} will turn Do Not Disturb off for this rule. Note that Do Not Disturb
     * might still be enabled globally if other conditions are in a {@link #STATE_TRUE} state.
     */
    @State
    public final int state;

    @SystemApi
    public final int flags;
    @SystemApi
    public final int icon;

    /**
     * An object representing the current state of a {@link android.app.AutomaticZenRule}.
     * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule
     * @param summary a user visible description of the rule state.
     */
    public Condition(Uri id, String summary, int state) {
        this(id, summary, "", "", -1, state, FLAG_RELEVANT_ALWAYS);
    }

    @SystemApi
    public Condition(Uri id, String summary, String line1, String line2, int icon,
            int state, int flags) {
        if (id == null) throw new IllegalArgumentException("id is required");
        if (summary == null) throw new IllegalArgumentException("summary is required");
        if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state);
        this.id = id;
        this.summary = summary;
        this.line1 = line1;
        this.line2 = line2;
        this.icon = icon;
        this.state = state;
        this.flags = flags;
    }

    public Condition(Parcel source) {
        this((Uri)source.readParcelable(Condition.class.getClassLoader()),
                source.readString(),
                source.readString(),
                source.readString(),
                source.readInt(),
                source.readInt(),
                source.readInt());
    }

    private static boolean isValidState(int state) {
        return state >= STATE_FALSE && state <= STATE_ERROR;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(id, 0);
        dest.writeString(summary);
        dest.writeString(line1);
        dest.writeString(line2);
        dest.writeInt(icon);
        dest.writeInt(state);
        dest.writeInt(this.flags);
    }

    @Override
    public String toString() {
        return new StringBuilder(Condition.class.getSimpleName()).append('[')
            .append("id=").append(id)
            .append(",summary=").append(summary)
            .append(",line1=").append(line1)
            .append(",line2=").append(line2)
            .append(",icon=").append(icon)
            .append(",state=").append(stateToString(state))
            .append(",flags=").append(flags)
            .append(']').toString();
    }

    @SystemApi
    public static String stateToString(int state) {
        if (state == STATE_FALSE) return "STATE_FALSE";
        if (state == STATE_TRUE) return "STATE_TRUE";
        if (state == STATE_UNKNOWN) return "STATE_UNKNOWN";
        if (state == STATE_ERROR) return "STATE_ERROR";
        throw new IllegalArgumentException("state is invalid: " + state);
    }

    @SystemApi
    public static String relevanceToString(int flags) {
        final boolean now = (flags & FLAG_RELEVANT_NOW) != 0;
        final boolean always = (flags & FLAG_RELEVANT_ALWAYS) != 0;
        if (!now && !always) return "NONE";
        if (now && always) return "NOW, ALWAYS";
        return now ? "NOW" : "ALWAYS";
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Condition)) return false;
        if (o == this) return true;
        final Condition other = (Condition) o;
        return Objects.equals(other.id, id)
                && Objects.equals(other.summary, summary)
                && Objects.equals(other.line1, line1)
                && Objects.equals(other.line2, line2)
                && other.icon == icon
                && other.state == state
                && other.flags == flags;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, summary, line1, line2, icon, state, flags);
    }

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

    @SystemApi
    public Condition copy() {
        final Parcel parcel = Parcel.obtain();
        try {
            writeToParcel(parcel, 0);
            parcel.setDataPosition(0);
            return new Condition(parcel);
        } finally {
            parcel.recycle();
        }
    }

    @SystemApi
    public static Uri.Builder newId(Context context) {
        return new Uri.Builder()
                .scheme(Condition.SCHEME)
                .authority(context.getPackageName());
    }

    @SystemApi
    public static boolean isValidId(Uri id, String pkg) {
        return id != null && SCHEME.equals(id.getScheme()) && pkg.equals(id.getAuthority());
    }

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

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