// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugin.platform;

import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.Log;
import io.flutter.embedding.android.AndroidTouchProcessor;
import io.flutter.util.ViewUtils;
import io.flutter.view.TextureRegistry;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Wraps a platform view to intercept gestures and project this view onto a {@link SurfaceTexture}.
 *
 * <p>An Android platform view is composed by the engine using a {@code TextureLayer}. The view is
 * embeded to the Android view hierarchy like a normal view, but it's projected onto a {@link
 * SurfaceTexture}, so it can be efficiently composed by the engine.
 *
 * <p>Since the view is in the Android view hierarchy, keyboard and accessibility interactions
 * behave normally.
 */
@TargetApi(23)
class PlatformViewWrapper extends FrameLayout {
  private static final String TAG = "PlatformViewWrapper";

  private int prevLeft;
  private int prevTop;
  private int left;
  private int top;
  private int bufferWidth;
  private int bufferHeight;
  private SurfaceTexture tx;
  private Surface surface;
  private AndroidTouchProcessor touchProcessor;

  @Nullable @VisibleForTesting ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener;
  private final AtomicLong pendingFramesCount = new AtomicLong(0L);

  private final TextureRegistry.OnFrameConsumedListener frameConsumedListener =
      new TextureRegistry.OnFrameConsumedListener() {
        @Override
        public void onFrameConsumed() {
          if (Build.VERSION.SDK_INT == 29) {
            pendingFramesCount.decrementAndGet();
          }
        }
      };

  private boolean shouldRecreateSurfaceForLowMemory = false;
  private final TextureRegistry.OnTrimMemoryListener trimMemoryListener =
      new TextureRegistry.OnTrimMemoryListener() {
        @Override
        public void onTrimMemory(int level) {
          // When a memory pressure warning is received and the level equal {@code
          // ComponentCallbacks2.TRIM_MEMORY_COMPLETE}, the Android system releases the underlying
          // surface. If we continue to use the surface (e.g., call lockHardwareCanvas), a crash
          // occurs, and we found that this crash appeared on Android10 and above.
          // See https://github.com/flutter/flutter/issues/103870 for more details.
          //
          // Here our workaround is to recreate the surface before using it.
          if (level == TRIM_MEMORY_COMPLETE && Build.VERSION.SDK_INT >= 29) {
            shouldRecreateSurfaceForLowMemory = true;
          }
        }
      };

  private void onFrameProduced() {
    if (Build.VERSION.SDK_INT == 29) {
      pendingFramesCount.incrementAndGet();
    }
  }

  private void recreateSurfaceIfNeeded() {
    if (shouldRecreateSurfaceForLowMemory) {
      if (surface != null) {
        surface.release();
      }
      surface = createSurface(tx);
      shouldRecreateSurfaceForLowMemory = false;
    }
  }

  private boolean shouldDrawToSurfaceNow() {
    if (Build.VERSION.SDK_INT == 29) {
      return pendingFramesCount.get() <= 0L;
    }
    return true;
  }

  public PlatformViewWrapper(@NonNull Context context) {
    super(context);
    setWillNotDraw(false);
  }

  public PlatformViewWrapper(
      @NonNull Context context, @NonNull TextureRegistry.SurfaceTextureEntry textureEntry) {
    this(context);
    textureEntry.setOnFrameConsumedListener(frameConsumedListener);
    textureEntry.setOnTrimMemoryListener(trimMemoryListener);
    setTexture(textureEntry.surfaceTexture());
  }

  /**
   * Sets the touch processor that allows to intercept gestures.
   *
   * @param newTouchProcessor The touch processor.
   */
  public void setTouchProcessor(@Nullable AndroidTouchProcessor newTouchProcessor) {
    touchProcessor = newTouchProcessor;
  }

  /**
   * Sets the texture where the view is projected onto.
   *
   * <p>{@link PlatformViewWrapper} doesn't take ownership of the {@link SurfaceTexture}. As a
   * result, the caller is responsible for releasing the texture.
   *
   * <p>{@link io.flutter.view.TextureRegistry} is responsible for creating and registering textures
   * in the engine. Therefore, the engine is responsible for also releasing the texture.
   *
   * @param newTx The texture where the view is projected onto.
   */
  @SuppressLint("NewApi")
  public void setTexture(@Nullable SurfaceTexture newTx) {
    if (Build.VERSION.SDK_INT < 23) {
      Log.e(
          TAG,
          "Platform views cannot be displayed below API level 23. "
              + "You can prevent this issue by setting `minSdkVersion: 23` in build.gradle.");
      return;
    }

    tx = newTx;

    if (bufferWidth > 0 && bufferHeight > 0) {
      tx.setDefaultBufferSize(bufferWidth, bufferHeight);
    }

    if (surface != null) {
      surface.release();
    }
    surface = createSurface(newTx);

    // Fill the entire canvas with a transparent color.
    // As a result, the background color of the platform view container is displayed
    // to the user until the platform view draws its first frame.
    final Canvas canvas = surface.lockHardwareCanvas();
    try {
      if (Build.VERSION.SDK_INT >= 29) {
        canvas.drawColor(Color.TRANSPARENT, BlendMode.CLEAR);
      } else {
        canvas.drawColor(Color.TRANSPARENT);
      }
      onFrameProduced();
    } finally {
      surface.unlockCanvasAndPost(canvas);
    }
  }

  @NonNull
  @VisibleForTesting
  protected Surface createSurface(@NonNull SurfaceTexture tx) {
    return new Surface(tx);
  }

  /** Returns the texture where the view is projected. */
  @Nullable
  public SurfaceTexture getTexture() {
    return tx;
  }

  /**
   * Sets the layout parameters for this view.
   *
   * @param params The new parameters.
   */
  public void setLayoutParams(@NonNull FrameLayout.LayoutParams params) {
    super.setLayoutParams(params);

    left = params.leftMargin;
    top = params.topMargin;
  }

  /**
   * Sets the size of the image buffer.
   *
   * @param width The width of the screen buffer.
   * @param height The height of the screen buffer.
   */
  public void setBufferSize(int width, int height) {
    bufferWidth = width;
    bufferHeight = height;
    if (tx != null) {
      tx.setDefaultBufferSize(width, height);
    }
  }

  /** Returns the image buffer width. */
  public int getBufferWidth() {
    return bufferWidth;
  }

  /** Returns the image buffer height. */
  public int getBufferHeight() {
    return bufferHeight;
  }

  /** Releases the surface. */
  public void release() {
    // Don't release the texture.
    tx = null;
    if (surface != null) {
      surface.release();
      surface = null;
    }
  }

  @Override
  public boolean onInterceptTouchEvent(@NonNull MotionEvent event) {
    return true;
  }

  /** Used on Android O+, {@link invalidateChildInParent} used for previous versions. */
  @SuppressLint("NewApi")
  @Override
  public void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
    super.onDescendantInvalidated(child, target);
    invalidate();
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    invalidate();
    return super.invalidateChildInParent(location, dirty);
  }

  @Override
  @SuppressLint("NewApi")
  public void draw(Canvas canvas) {
    if (surface == null) {
      super.draw(canvas);
      Log.e(TAG, "Platform view cannot be composed without a surface.");
      return;
    }
    if (!surface.isValid()) {
      Log.e(TAG, "Invalid surface. The platform view cannot be displayed.");
      return;
    }
    if (tx == null || tx.isReleased()) {
      Log.e(TAG, "Invalid texture. The platform view cannot be displayed.");
      return;
    }
    // We've observed on Android Q that we have to wait for the consumer of {@link SurfaceTexture}
    // to consume the last image before continuing to draw, otherwise subsequent calls to
    // {@code dequeueBuffer} to request a free buffer from the {@link BufferQueue} will fail.
    // See https://github.com/flutter/flutter/issues/98722
    if (!shouldDrawToSurfaceNow()) {
      // If there are still frames that are not consumed, we will draw them next time.
      invalidate();
    } else {
      // We try to recreate the surface before using it to avoid the crash:
      // https://github.com/flutter/flutter/issues/103870
      recreateSurfaceIfNeeded();

      // Override the canvas that this subtree of views will use to draw.
      final Canvas surfaceCanvas = surface.lockHardwareCanvas();
      try {
        // Clear the current pixels in the canvas.
        // This helps when a WebView renders an HTML document with transparent background.
        if (Build.VERSION.SDK_INT >= 29) {
          surfaceCanvas.drawColor(Color.TRANSPARENT, BlendMode.CLEAR);
        } else {
          surfaceCanvas.drawColor(Color.TRANSPARENT);
        }
        super.draw(surfaceCanvas);
        onFrameProduced();
      } finally {
        surface.unlockCanvasAndPost(surfaceCanvas);
      }
    }
  }

  @Override
  @SuppressLint("ClickableViewAccessibility")
  public boolean onTouchEvent(@NonNull MotionEvent event) {
    if (touchProcessor == null) {
      return super.onTouchEvent(event);
    }
    final Matrix screenMatrix = new Matrix();
    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        prevLeft = left;
        prevTop = top;
        screenMatrix.postTranslate(left, top);
        break;
      case MotionEvent.ACTION_MOVE:
        // While the view is dragged, use the left and top positions as
        // they were at the moment the touch event fired.
        screenMatrix.postTranslate(prevLeft, prevTop);
        prevLeft = left;
        prevTop = top;
        break;
      case MotionEvent.ACTION_UP:
      default:
        screenMatrix.postTranslate(left, top);
        break;
    }
    return touchProcessor.onTouchEvent(event, screenMatrix);
  }

  public void setOnDescendantFocusChangeListener(@NonNull OnFocusChangeListener userFocusListener) {
    unsetOnDescendantFocusChangeListener();
    final ViewTreeObserver observer = getViewTreeObserver();
    if (observer.isAlive() && activeFocusListener == null) {
      activeFocusListener =
          new ViewTreeObserver.OnGlobalFocusChangeListener() {
            @Override
            public void onGlobalFocusChanged(View oldFocus, View newFocus) {
              userFocusListener.onFocusChange(
                  PlatformViewWrapper.this, ViewUtils.childHasFocus(PlatformViewWrapper.this));
            }
          };
      observer.addOnGlobalFocusChangeListener(activeFocusListener);
    }
  }

  public void unsetOnDescendantFocusChangeListener() {
    final ViewTreeObserver observer = getViewTreeObserver();
    if (observer.isAlive() && activeFocusListener != null) {
      final ViewTreeObserver.OnGlobalFocusChangeListener currFocusListener = activeFocusListener;
      activeFocusListener = null;
      observer.removeOnGlobalFocusChangeListener(currFocusListener);
    }
  }
}
