// 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.view;

import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import io.flutter.Log;
import io.flutter.app.FlutterPluginRegistry;
import io.flutter.embedding.engine.FlutterEngine.EngineLifecycleListener;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
import io.flutter.plugin.common.*;
import java.nio.ByteBuffer;

/**
 * @deprecated {@link io.flutter.embedding.android.FlutterView} is the new API that now replaces
 *     this class. See https://flutter.dev/go/android-project-migration for more migration details.
 */
@Deprecated
public class FlutterNativeView implements BinaryMessenger {
  private static final String TAG = "FlutterNativeView";

  private final FlutterPluginRegistry mPluginRegistry;
  private final DartExecutor dartExecutor;
  private FlutterView mFlutterView;
  private final FlutterJNI mFlutterJNI;
  private final Context mContext;
  private boolean applicationIsRunning;

  private final FlutterUiDisplayListener flutterUiDisplayListener =
      new FlutterUiDisplayListener() {
        @Override
        public void onFlutterUiDisplayed() {
          if (mFlutterView == null) {
            return;
          }
          mFlutterView.onFirstFrame();
        }

        @Override
        public void onFlutterUiNoLongerDisplayed() {
          // no-op
        }
      };

  public FlutterNativeView(@NonNull Context context) {
    this(context, false);
  }

  public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
    if (isBackgroundView) {
      Log.w(TAG, "'isBackgroundView' is no longer supported and will be ignored");
    }
    mContext = context;
    mPluginRegistry = new FlutterPluginRegistry(this, context);
    mFlutterJNI = new FlutterJNI();
    mFlutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
    this.dartExecutor = new DartExecutor(mFlutterJNI, context.getAssets());
    mFlutterJNI.addEngineLifecycleListener(new EngineLifecycleListenerImpl());
    attach(this);
    assertAttached();
  }

  public void detachFromFlutterView() {
    mPluginRegistry.detach();
    mFlutterView = null;
  }

  public void destroy() {
    mPluginRegistry.destroy();
    dartExecutor.onDetachedFromJNI();
    mFlutterView = null;
    mFlutterJNI.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);
    mFlutterJNI.detachFromNativeAndReleaseResources();
    applicationIsRunning = false;
  }

  @NonNull
  public DartExecutor getDartExecutor() {
    return dartExecutor;
  }

  @NonNull
  public FlutterPluginRegistry getPluginRegistry() {
    return mPluginRegistry;
  }

  public void attachViewAndActivity(FlutterView flutterView, Activity activity) {
    mFlutterView = flutterView;
    mPluginRegistry.attach(flutterView, activity);
  }

  public boolean isAttached() {
    return mFlutterJNI.isAttached();
  }

  public void assertAttached() {
    if (!isAttached()) throw new AssertionError("Platform view is not attached");
  }

  public void runFromBundle(FlutterRunArguments args) {
    if (args.entrypoint == null) {
      throw new AssertionError("An entrypoint must be specified");
    }
    assertAttached();
    if (applicationIsRunning)
      throw new AssertionError("This Flutter engine instance is already running an application");
    mFlutterJNI.runBundleAndSnapshotFromLibrary(
        args.bundlePath,
        args.entrypoint,
        args.libraryPath,
        mContext.getResources().getAssets(),
        null);

    applicationIsRunning = true;
  }

  public boolean isApplicationRunning() {
    return applicationIsRunning;
  }

  public static String getObservatoryUri() {
    return FlutterJNI.getObservatoryUri();
  }

  @Override
  @UiThread
  public TaskQueue makeBackgroundTaskQueue(TaskQueueOptions options) {
    return dartExecutor.getBinaryMessenger().makeBackgroundTaskQueue(options);
  }

  @Override
  @UiThread
  public void send(String channel, ByteBuffer message) {
    dartExecutor.getBinaryMessenger().send(channel, message);
  }

  @Override
  @UiThread
  public void send(String channel, ByteBuffer message, BinaryReply callback) {
    if (!isAttached()) {
      Log.d(TAG, "FlutterView.send called on a detached view, channel=" + channel);
      return;
    }

    dartExecutor.getBinaryMessenger().send(channel, message, callback);
  }

  @Override
  @UiThread
  public void setMessageHandler(String channel, BinaryMessageHandler handler) {
    dartExecutor.getBinaryMessenger().setMessageHandler(channel, handler);
  }

  @Override
  @UiThread
  public void setMessageHandler(String channel, BinaryMessageHandler handler, TaskQueue taskQueue) {
    dartExecutor.getBinaryMessenger().setMessageHandler(channel, handler, taskQueue);
  }

  @Override
  public void enableBufferingIncomingMessages() {}

  @Override
  public void disableBufferingIncomingMessages() {}

  /*package*/ FlutterJNI getFlutterJNI() {
    return mFlutterJNI;
  }

  private void attach(FlutterNativeView view) {
    mFlutterJNI.attachToNative();
    dartExecutor.onAttachedToJNI();
  }

  private final class EngineLifecycleListenerImpl implements EngineLifecycleListener {
    // Called by native to notify right before the engine is restarted (cold reload).
    @SuppressWarnings("unused")
    public void onPreEngineRestart() {
      if (mFlutterView != null) {
        mFlutterView.resetAccessibilityTree();
      }
      if (mPluginRegistry == null) {
        return;
      }
      mPluginRegistry.onPreEngineRestart();
    }

    public void onEngineWillDestroy() {
      // The old embedding doesn't actually have a FlutterEngine. It interacts with the JNI
      // directly.
    }
  }
}
