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

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Rect;
import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
import android.util.DebugUtils;
import android.view.View;

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

/**
 * Abstraction of a "Smart Suggestion" component responsible to embed the autofill UI provided by
 * the intelligence service.
 *
 * <p>The Smart Suggestion can embed the autofill UI in 3 distinct places:
 *
 * <ul>
 *   <li>A small area associated with suggestions (like a small strip in the top of the IME),
 *   returned by {@link #getSuggestionArea()}
 *   <li>The full area (like the full IME window), returned by {@link #getFullArea()}
 *   <li>A subset of the aforementioned areas, returned by {@link Area#getSubArea(Rect)}
 * </ul>
 *
 * <p>The Smart Suggestion is represented by a {@link Area} object that contains the
 * dimensions the smart suggestion window, so the service can use it to calculate the size of the
 * view that will be passed to {@link FillWindow#update(Area, View, long)}.
 *
 * @hide
 */
@SystemApi
public abstract class PresentationParams {

    /**
     * Flag indicating the Smart Suggestion is hosted in the top of its container.
     */
    public static final int FLAG_HINT_GRAVITY_TOP = 0x1;

    /**
     * Flag indicating the Smart Suggestion is hosted in the bottom of its container.
     */
    public static final int FLAG_HINT_GRAVITY_BOTTOM = 0x2;

    /**
     * Flag indicating the Smart Suggestion is hosted in the left of its container.
     */
    public static final int FLAG_HINT_GRAVITY_LEFT = 0x4;

    /**
     * Flag indicating the Smart Suggestion is hosted in the right of its container.
     */
    public static final int FLAG_HINT_GRAVITY_RIGHT = 0x8;

    /**
     * Flag indicating the Smart Suggestion is hosted by the IME.
     */
    public static final int FLAG_HOST_IME = 0x10;

    /**
     * Flag indicating the Smart Suggestion is hosted by the Android System as a floating popup
     * window.
     */
    public static final int FLAG_HOST_SYSTEM = 0x20;

    /** @hide */
    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
            FLAG_HINT_GRAVITY_TOP,
            FLAG_HINT_GRAVITY_BOTTOM,
            FLAG_HINT_GRAVITY_LEFT,
            FLAG_HINT_GRAVITY_RIGHT,
            FLAG_HOST_IME,
            FLAG_HOST_SYSTEM
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Flags {}


    // /** @hide */
    PresentationParams() {}

    /**
     * Gets the area of the suggestion strip for the given {@code metadata}
     *
     * @return strip dimensions, or {@code null} if the Smart Suggestion provider does not support
     * suggestions strip.
     */
    @Nullable
    public Area getSuggestionArea() {
        return null;
    }

    /**
     * Gets the full area for the of the Smart Suggestion provider.
     *
     * @return full dimensions, or {@code null} if the Smart Suggestion provider does not support
     * embeding the UI on its full area.
     */
    @Nullable
    public Area getFullArea() {
        return null;
    }

    /**
     * Gets flags associated with the Smart Suggestion.
     *
     * @return any combination of {@link #FLAG_HINT_GRAVITY_TOP},
     * {@link #FLAG_HINT_GRAVITY_BOTTOM}, {@link #FLAG_HINT_GRAVITY_LEFT},
     * {@link #FLAG_HINT_GRAVITY_RIGHT}, {@link #FLAG_HOST_IME}, or
     * {@link #FLAG_HOST_SYSTEM},
     */
    public @Flags int getFlags() {
        return 0;
    }

    /** @hide */
    void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
        final int flags = getFlags();
        if (flags > 0) {
            pw.print(prefix); pw.print("flags: "); pw.println(flagsToString(flags));
        }
    }

    private static String flagsToString(int flags) {
        return DebugUtils.flagsToString(PresentationParams.class, "FLAG_", flags);
    }

    /**
     * Area associated with a {@link PresentationParams Smart Suggestions} provider.
     *
     * @hide
     * */
    @SystemApi
    public abstract static class Area {

        /** @hide */
        public final AutofillProxy proxy;

        private final Rect mBounds;

        private Area(@NonNull AutofillProxy proxy, @NonNull Rect bounds) {
            this.proxy = proxy;
            mBounds = bounds;
        }

        /**
         * Gets the area boundaries.
         */
        @NonNull
        public Rect getBounds() {
            return mBounds;
        }

        /**
         * Gets a subarea limited by given boundaries.
         *
         * @param bounds boundaries relative to this Area.
         *
         * @throws {@link IllegalArgumentException} if the {@code bounds} is not fully-contained
         * inside this full Area.
         *
         * @return new subarea, or {@code null} if the Smart Suggestion host does not support such
         * subaarea.
         */
        @Nullable
        public Area getSubArea(@NonNull Rect bounds) {
            // TODO(b/111330312): implement / check boundaries / throw IAE / add unit test
            return null;
        }

        @Override
        public String toString() {
            return mBounds.toString();
        }
    }

    /**
     * System-provided poup window anchored to a view.
     *
     * <p>Used just for debugging purposes.
     *
     * @hide
     */
    public static final class SystemPopupPresentationParams extends PresentationParams {
        private final Area mSuggestionArea;

        public SystemPopupPresentationParams(@NonNull AutofillProxy proxy, @NonNull Rect rect) {
            mSuggestionArea = new Area(proxy, rect) {};
        }

        @Override
        public Area getSuggestionArea() {
            return mSuggestionArea;
        }

        @Override
        public int getFlags() {
            return FLAG_HOST_SYSTEM | FLAG_HINT_GRAVITY_BOTTOM;
        }

        @Override
        void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
            super.dump(prefix, pw);
            pw.print(prefix); pw.print("area: "); pw.println(mSuggestionArea);
        }
    }
}
