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

import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.LEFT;
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.TOP;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.text.TextUtils;
import android.util.Log;
import android.util.PathParser;

import com.android.internal.annotations.VisibleForTesting;

import java.util.Locale;
import java.util.Objects;

/**
 * In order to accept the cutout specification for all of edges in devices, the specification
 * parsing method is extracted from
 * {@link android.view.DisplayCutout#fromResourcesRectApproximation(Resources, int, int)} to be
 * the specified class for parsing the specification.
 * BNF definition:
 * <ul>
 *      <li>Cutouts Specification = ([Cutout Delimiter],Cutout Specification) {...}, [Dp] ; </li>
 *      <li>Cutout Specification  = [Vertical Position], (SVG Path Element), [Horizontal Position]
 *                                  [Bind Cutout] ;</li>
 *      <li>Vertical Position     = "@bottom" | "@center_vertical" ;</li>
 *      <li>Horizontal Position   = "@left" | "@right" ;</li>
 *      <li>Bind Cutout           = "@bind_left_cutout" | "@bind_right_cutout" ;</li>
 *      <li>Cutout Delimiter      = "@cutout" ;</li>
 *      <li>Dp                    = "@dp"</li>
 * </ul>
 *
 * <ul>
 *     <li>Vertical position is top by default if there is neither "@bottom" nor "@center_vertical"
 *     </li>
 *     <li>Horizontal position is center horizontal by default if there is neither "@left" nor
 *     "@right".</li>
 *     <li>@bottom make the cutout piece bind to bottom edge.</li>
 *     <li>both of @bind_left_cutout and @bind_right_cutout are use to claim the cutout belong to
 *     left or right edge cutout.</li>
 * </ul>
 *
 * @hide
 */
@VisibleForTesting(visibility = PACKAGE)
public class CutoutSpecification {
    private static final String TAG = "CutoutSpecification";
    private static final boolean DEBUG = false;

    private static final int MINIMAL_ACCEPTABLE_PATH_LENGTH = "H1V1Z".length();

    private static final char MARKER_START_CHAR = '@';
    private static final String DP_MARKER = MARKER_START_CHAR + "dp";

    private static final String BOTTOM_MARKER = MARKER_START_CHAR + "bottom";
    private static final String RIGHT_MARKER = MARKER_START_CHAR + "right";
    private static final String LEFT_MARKER = MARKER_START_CHAR + "left";
    private static final String CUTOUT_MARKER = MARKER_START_CHAR + "cutout";
    private static final String CENTER_VERTICAL_MARKER = MARKER_START_CHAR + "center_vertical";

    /* By default, it's top bound cutout. That's why TOP_BOUND_CUTOUT_MARKER is not defined */
    private static final String BIND_RIGHT_CUTOUT_MARKER = MARKER_START_CHAR + "bind_right_cutout";
    private static final String BIND_LEFT_CUTOUT_MARKER = MARKER_START_CHAR + "bind_left_cutout";

    private final Path mPath;
    private final Rect mLeftBound;
    private final Rect mTopBound;
    private final Rect mRightBound;
    private final Rect mBottomBound;
    private final Insets mInsets;

    private CutoutSpecification(@NonNull Parser parser) {
        mPath = parser.mPath;
        mLeftBound = parser.mLeftBound;
        mTopBound = parser.mTopBound;
        mRightBound = parser.mRightBound;
        mBottomBound = parser.mBottomBound;
        mInsets = parser.mInsets;

        if (DEBUG) {
            Log.d(TAG, String.format(Locale.ENGLISH,
                    "left cutout = %s, top cutout = %s, right cutout = %s, bottom cutout = %s",
                    mLeftBound != null ? mLeftBound.toString() : "",
                    mTopBound != null ? mTopBound.toString() : "",
                    mRightBound != null ? mRightBound.toString() : "",
                    mBottomBound != null ? mBottomBound.toString() : ""));
        }
    }

    @VisibleForTesting(visibility = PACKAGE)
    @Nullable
    public Path getPath() {
        return mPath;
    }

    @VisibleForTesting(visibility = PACKAGE)
    @Nullable
    public Rect getLeftBound() {
        return mLeftBound;
    }

    @VisibleForTesting(visibility = PACKAGE)
    @Nullable
    public Rect getTopBound() {
        return mTopBound;
    }

    @VisibleForTesting(visibility = PACKAGE)
    @Nullable
    public Rect getRightBound() {
        return mRightBound;
    }

    @VisibleForTesting(visibility = PACKAGE)
    @Nullable
    public Rect getBottomBound() {
        return mBottomBound;
    }

    /**
     * To count the safe inset according to the cutout bounds and waterfall inset.
     *
     * @return the safe inset.
     */
    @VisibleForTesting(visibility = PACKAGE)
    @NonNull
    public Rect getSafeInset() {
        return mInsets.toRect();
    }

    private static int decideWhichEdge(boolean isTopEdgeShortEdge,
            boolean isShortEdge, boolean isStart) {
        return (isTopEdgeShortEdge)
                ? ((isShortEdge) ? (isStart ? TOP : BOTTOM) : (isStart ? LEFT : RIGHT))
                : ((isShortEdge) ? (isStart ? LEFT : RIGHT) : (isStart ? TOP : BOTTOM));
    }

    /**
     * The CutoutSpecification Parser.
     */
    @VisibleForTesting(visibility = PACKAGE)
    public static class Parser {
        private final boolean mIsShortEdgeOnTop;
        private final float mDensity;
        private final int mDisplayWidth;
        private final int mDisplayHeight;
        private final Matrix mMatrix;
        private Insets mInsets;
        private int mSafeInsetLeft;
        private int mSafeInsetTop;
        private int mSafeInsetRight;
        private int mSafeInsetBottom;

        private final Rect mTmpRect = new Rect();
        private final RectF mTmpRectF = new RectF();

        private boolean mInDp;

        private Path mPath;
        private Rect mLeftBound;
        private Rect mTopBound;
        private Rect mRightBound;
        private Rect mBottomBound;

        private boolean mPositionFromLeft = false;
        private boolean mPositionFromRight = false;
        private boolean mPositionFromBottom = false;
        private boolean mPositionFromCenterVertical = false;

        private boolean mBindLeftCutout = false;
        private boolean mBindRightCutout = false;
        private boolean mBindBottomCutout = false;

        private boolean mIsTouchShortEdgeStart;
        private boolean mIsTouchShortEdgeEnd;
        private boolean mIsCloserToStartSide;

        /**
         * The constructor of the CutoutSpecification parser to parse the specification of cutout.
         * @param density the display density.
         * @param displayWidth the display width.
         * @param displayHeight the display height.
         */
        @VisibleForTesting(visibility = PACKAGE)
        public Parser(float density, int displayWidth, int displayHeight) {
            mDensity = density;
            mDisplayWidth = displayWidth;
            mDisplayHeight = displayHeight;
            mMatrix = new Matrix();
            mIsShortEdgeOnTop = mDisplayWidth < mDisplayHeight;
        }

        private void computeBoundsRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
            mTmpRectF.setEmpty();
            p.computeBounds(mTmpRectF, false /* unused */);
            mTmpRectF.round(inoutRect);
            inoutRegion.op(inoutRect, Region.Op.UNION);
        }

        private void resetStatus(StringBuilder sb) {
            sb.setLength(0);
            mPositionFromBottom = false;
            mPositionFromLeft = false;
            mPositionFromRight = false;
            mPositionFromCenterVertical = false;

            mBindLeftCutout = false;
            mBindRightCutout = false;
            mBindBottomCutout = false;
        }

        private void translateMatrix() {
            final float offsetX;
            if (mPositionFromRight) {
                offsetX = mDisplayWidth;
            } else if (mPositionFromLeft) {
                offsetX = 0;
            } else {
                offsetX = mDisplayWidth / 2f;
            }

            final float offsetY;
            if (mPositionFromBottom) {
                offsetY = mDisplayHeight;
            } else if (mPositionFromCenterVertical) {
                offsetY = mDisplayHeight / 2f;
            } else {
                offsetY = 0;
            }

            mMatrix.reset();
            if (mInDp) {
                mMatrix.postScale(mDensity, mDensity);
            }
            mMatrix.postTranslate(offsetX, offsetY);
        }

        private int computeSafeInsets(int gravity, Rect rect) {
            if (gravity == LEFT && rect.right > 0 && rect.right < mDisplayWidth) {
                return rect.right;
            } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mDisplayHeight) {
                return rect.bottom;
            } else if (gravity == RIGHT && rect.left > 0 && rect.left < mDisplayWidth) {
                return mDisplayWidth - rect.left;
            } else if (gravity == BOTTOM && rect.top > 0 && rect.top < mDisplayHeight) {
                return mDisplayHeight - rect.top;
            }
            return 0;
        }

        private void setSafeInset(int gravity, int inset) {
            if (gravity == LEFT) {
                mSafeInsetLeft = inset;
            } else if (gravity == TOP) {
                mSafeInsetTop = inset;
            } else if (gravity == RIGHT) {
                mSafeInsetRight = inset;
            } else if (gravity == BOTTOM) {
                mSafeInsetBottom = inset;
            }
        }

        private int getSafeInset(int gravity) {
            if (gravity == LEFT) {
                return mSafeInsetLeft;
            } else if (gravity == TOP) {
                return mSafeInsetTop;
            } else if (gravity == RIGHT) {
                return mSafeInsetRight;
            } else if (gravity == BOTTOM) {
                return mSafeInsetBottom;
            }
            return 0;
        }

        @NonNull
        private Rect onSetEdgeCutout(boolean isStart, boolean isShortEdge, @NonNull Rect rect) {
            final int gravity;
            if (isShortEdge) {
                gravity = decideWhichEdge(mIsShortEdgeOnTop, true, isStart);
            } else {
                if (mIsTouchShortEdgeStart && mIsTouchShortEdgeEnd) {
                    gravity = decideWhichEdge(mIsShortEdgeOnTop, false, isStart);
                } else if (mIsTouchShortEdgeStart || mIsTouchShortEdgeEnd) {
                    gravity = decideWhichEdge(mIsShortEdgeOnTop, true,
                            mIsCloserToStartSide);
                } else {
                    gravity = decideWhichEdge(mIsShortEdgeOnTop, isShortEdge, isStart);
                }
            }

            int oldSafeInset = getSafeInset(gravity);
            int newSafeInset = computeSafeInsets(gravity, rect);
            if (oldSafeInset < newSafeInset) {
                setSafeInset(gravity, newSafeInset);
            }

            return new Rect(rect);
        }

        private void setEdgeCutout(@NonNull Path newPath) {
            if (mBindRightCutout && mRightBound == null) {
                mRightBound = onSetEdgeCutout(false, !mIsShortEdgeOnTop, mTmpRect);
            } else if (mBindLeftCutout && mLeftBound == null) {
                mLeftBound = onSetEdgeCutout(true, !mIsShortEdgeOnTop, mTmpRect);
            } else if (mBindBottomCutout && mBottomBound == null) {
                mBottomBound = onSetEdgeCutout(false, mIsShortEdgeOnTop, mTmpRect);
            } else if (!(mBindBottomCutout || mBindLeftCutout || mBindRightCutout)
                    && mTopBound == null) {
                mTopBound = onSetEdgeCutout(true, mIsShortEdgeOnTop, mTmpRect);
            } else {
                return;
            }

            if (mPath != null) {
                mPath.addPath(newPath);
            } else {
                mPath = newPath;
            }
        }

        private void parseSvgPathSpec(Region region, String spec) {
            if (TextUtils.length(spec) < MINIMAL_ACCEPTABLE_PATH_LENGTH) {
                Log.e(TAG, "According to SVG definition, it shouldn't happen");
                return;
            }
            spec.trim();
            translateMatrix();

            final Path newPath = PathParser.createPathFromPathData(spec);
            newPath.transform(mMatrix);
            computeBoundsRectAndAddToRegion(newPath, region, mTmpRect);

            if (DEBUG) {
                Log.d(TAG, String.format(Locale.ENGLISH,
                        "hasLeft = %b, hasRight = %b, hasBottom = %b, hasCenterVertical = %b",
                        mPositionFromLeft, mPositionFromRight, mPositionFromBottom,
                        mPositionFromCenterVertical));
                Log.d(TAG, "region = " + region);
                Log.d(TAG, "spec = \"" + spec + "\" rect = " + mTmpRect + " newPath = " + newPath);
            }

            if (mTmpRect.isEmpty()) {
                return;
            }

            if (mIsShortEdgeOnTop) {
                mIsTouchShortEdgeStart = mTmpRect.top <= 0;
                mIsTouchShortEdgeEnd = mTmpRect.bottom >= mDisplayHeight;
                mIsCloserToStartSide = mTmpRect.centerY() < mDisplayHeight / 2;
            } else {
                mIsTouchShortEdgeStart = mTmpRect.left <= 0;
                mIsTouchShortEdgeEnd = mTmpRect.right >= mDisplayWidth;
                mIsCloserToStartSide = mTmpRect.centerX() < mDisplayWidth / 2;
            }

            setEdgeCutout(newPath);
        }

        private void parseSpecWithoutDp(@NonNull String specWithoutDp) {
            Region region = Region.obtain();
            StringBuilder sb = null;
            int currentIndex = 0;
            int lastIndex = 0;
            while ((currentIndex = specWithoutDp.indexOf(MARKER_START_CHAR, lastIndex)) != -1) {
                if (sb == null) {
                    sb = new StringBuilder(specWithoutDp.length());
                }
                sb.append(specWithoutDp, lastIndex, currentIndex);

                if (specWithoutDp.startsWith(LEFT_MARKER, currentIndex)) {
                    if (!mPositionFromRight) {
                        mPositionFromLeft = true;
                    }
                    currentIndex += LEFT_MARKER.length();
                } else if (specWithoutDp.startsWith(RIGHT_MARKER, currentIndex)) {
                    if (!mPositionFromLeft) {
                        mPositionFromRight = true;
                    }
                    currentIndex += RIGHT_MARKER.length();
                } else if (specWithoutDp.startsWith(BOTTOM_MARKER, currentIndex)) {
                    parseSvgPathSpec(region, sb.toString());
                    currentIndex += BOTTOM_MARKER.length();

                    /* prepare to parse the rest path */
                    resetStatus(sb);
                    mBindBottomCutout = true;
                    mPositionFromBottom = true;
                } else if (specWithoutDp.startsWith(CENTER_VERTICAL_MARKER, currentIndex)) {
                    parseSvgPathSpec(region, sb.toString());
                    currentIndex += CENTER_VERTICAL_MARKER.length();

                    /* prepare to parse the rest path */
                    resetStatus(sb);
                    mPositionFromCenterVertical = true;
                } else if (specWithoutDp.startsWith(CUTOUT_MARKER, currentIndex)) {
                    parseSvgPathSpec(region, sb.toString());
                    currentIndex += CUTOUT_MARKER.length();

                    /* prepare to parse the rest path */
                    resetStatus(sb);
                } else if (specWithoutDp.startsWith(BIND_LEFT_CUTOUT_MARKER, currentIndex)) {
                    mBindBottomCutout = false;
                    mBindRightCutout = false;
                    mBindLeftCutout = true;

                    currentIndex += BIND_LEFT_CUTOUT_MARKER.length();
                } else if (specWithoutDp.startsWith(BIND_RIGHT_CUTOUT_MARKER, currentIndex)) {
                    mBindBottomCutout = false;
                    mBindLeftCutout = false;
                    mBindRightCutout = true;

                    currentIndex += BIND_RIGHT_CUTOUT_MARKER.length();
                } else {
                    currentIndex += 1;
                }

                lastIndex = currentIndex;
            }

            if (sb == null) {
                parseSvgPathSpec(region, specWithoutDp);
            } else {
                sb.append(specWithoutDp, lastIndex, specWithoutDp.length());
                parseSvgPathSpec(region, sb.toString());
            }

            region.recycle();
        }

        /**
         * To parse specification string as the CutoutSpecification.
         *
         * @param originalSpec the specification string
         * @return the CutoutSpecification instance
         */
        @VisibleForTesting(visibility = PACKAGE)
        public CutoutSpecification parse(@NonNull String originalSpec) {
            Objects.requireNonNull(originalSpec);

            int dpIndex = originalSpec.lastIndexOf(DP_MARKER);
            mInDp = (dpIndex != -1);
            final String spec;
            if (dpIndex != -1) {
                spec = originalSpec.substring(0, dpIndex)
                        + originalSpec.substring(dpIndex + DP_MARKER.length());
            } else {
                spec = originalSpec;
            }

            parseSpecWithoutDp(spec);

            mInsets = Insets.of(mSafeInsetLeft, mSafeInsetTop, mSafeInsetRight, mSafeInsetBottom);
            return new CutoutSpecification(this);
        }
    }
}
