/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.react.fabric;

import android.annotation.SuppressLint;
import androidx.annotation.NonNull;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.NativeMap;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.fabric.events.EventBeatManager;
import com.facebook.react.uimanager.PixelUtil;

@DoNotStrip
@SuppressLint("MissingNativeLoadLibrary")
public class Binding {

  static {
    FabricSoLoader.staticInit();
  }

  @DoNotStrip private final HybridData mHybridData;

  private static native HybridData initHybrid();

  public Binding() {
    mHybridData = initHybrid();
  }

  private native void installFabricUIManager(
      long jsContextNativePointer,
      Object uiManager,
      EventBeatManager eventBeatManager,
      MessageQueueThread jsMessageQueueThread,
      ComponentFactoryDelegate componentsRegistry,
      Object reactNativeConfig);

  public native void startSurface(
      int surfaceId, @NonNull String moduleName, @NonNull NativeMap initialProps);

  public native void startSurfaceWithConstraints(
      int surfaceId,
      String moduleName,
      NativeMap initialProps,
      float minWidth,
      float maxWidth,
      float minHeight,
      float maxHeight,
      boolean isRTL,
      boolean doLeftAndRightSwapInRTL);

  public native void renderTemplateToSurface(int surfaceId, String uiTemplate);

  public native void stopSurface(int surfaceId);

  public native void setPixelDensity(float pointScaleFactor);

  public native void setConstraints(
      int surfaceId,
      float minWidth,
      float maxWidth,
      float minHeight,
      float maxHeight,
      boolean isRTL,
      boolean doLeftAndRightSwapInRTL);

  public void register(
      @NonNull JavaScriptContextHolder jsContext,
      @NonNull FabricUIManager fabricUIManager,
      @NonNull EventBeatManager eventBeatManager,
      @NonNull MessageQueueThread jsMessageQueueThread,
      @NonNull ComponentFactoryDelegate componentFactoryDelegate,
      @NonNull ReactNativeConfig reactNativeConfig) {
    fabricUIManager.setBinding(this);
    installFabricUIManager(
        jsContext.get(),
        fabricUIManager,
        eventBeatManager,
        jsMessageQueueThread,
        componentFactoryDelegate,
        reactNativeConfig);
    setPixelDensity(PixelUtil.getDisplayMetricDensity());
  }

  private native void uninstallFabricUIManager();

  public void unregister() {
    uninstallFabricUIManager();
  }
}
