// 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.plugins.webviewflutter;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.Nullable;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.WeakHashMap;

/**
 * Maintains instances used to communicate with the corresponding objects in Dart.
 *
 * <p>Objects stored in this container are represented by an object in Dart that is also stored in
 * an InstanceManager with the same identifier.
 *
 * <p>When an instance is added with an identifier, either can be used to retrieve the other.
 *
 * <p>Added instances are added as a weak reference and a strong reference. When the strong
 * reference is removed with `{@link #remove(long)}` and the weak reference is deallocated, the
 * `finalizationListener` is made with the instance's identifier. However, if the strong reference
 * is removed and then the identifier is retrieved with the intention to pass the identifier to Dart
 * (e.g. calling {@link #getIdentifierForStrongReference(Object)}), the strong reference to the
 * instance is recreated. The strong reference will then need to be removed manually again.
 */
@SuppressWarnings("unchecked")
public class InstanceManager {
  // Identifiers are locked to a specific range to avoid collisions with objects
  // created simultaneously from Dart.
  // Host uses identifiers >= 2^16 and Dart is expected to use values n where,
  // 0 <= n < 2^16.
  private static final long MIN_HOST_CREATED_IDENTIFIER = 65536;
  private static final long CLEAR_FINALIZED_WEAK_REFERENCES_INTERVAL = 30000;
  private static final String TAG = "InstanceManager";
  private static final String CLOSED_WARNING = "Method was called while the manager was closed.";

  /** Interface for listening when a weak reference of an instance is removed from the manager. */
  public interface FinalizationListener {
    void onFinalize(long identifier);
  }

  private final WeakHashMap<Object, Long> identifiers = new WeakHashMap<>();
  private final HashMap<Long, WeakReference<Object>> weakInstances = new HashMap<>();
  private final HashMap<Long, Object> strongInstances = new HashMap<>();

  private final ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
  private final HashMap<WeakReference<Object>, Long> weakReferencesToIdentifiers = new HashMap<>();

  private final Handler handler = new Handler(Looper.getMainLooper());

  private final FinalizationListener finalizationListener;

  private long nextIdentifier = MIN_HOST_CREATED_IDENTIFIER;
  private boolean isClosed = false;

  /**
   * Instantiate a new manager.
   *
   * <p>When the manager is no longer needed, {@link #close()} must be called.
   *
   * @param finalizationListener the listener for garbage collected weak references.
   * @return a new `InstanceManager`.
   */
  public static InstanceManager open(FinalizationListener finalizationListener) {
    return new InstanceManager(finalizationListener);
  }

  private InstanceManager(FinalizationListener finalizationListener) {
    this.finalizationListener = finalizationListener;
    handler.postDelayed(
        this::releaseAllFinalizedInstances, CLEAR_FINALIZED_WEAK_REFERENCES_INTERVAL);
  }

  /**
   * Removes `identifier` and its associated strongly referenced instance, if present, from the
   * manager.
   *
   * @param identifier the identifier paired to an instance.
   * @param <T> the expected return type.
   * @return the removed instance if the manager contains the given identifier, otherwise null if
   *     the manager doesn't contain the value or the manager is closed.
   */
  @Nullable
  public <T> T remove(long identifier) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return null;
    }
    return (T) strongInstances.remove(identifier);
  }

  /**
   * Retrieves the identifier paired with an instance.
   *
   * <p>If the manager contains `instance`, as a strong or weak reference, the strong reference to
   * `instance` will be recreated and will need to be removed again with {@link #remove(long)}.
   *
   * @param instance an instance that may be stored in the manager.
   * @return the identifier associated with `instance` if the manager contains the value, otherwise
   *     null if the manager doesn't contain the value or the manager is closed.
   */
  @Nullable
  public Long getIdentifierForStrongReference(Object instance) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return null;
    }
    final Long identifier = identifiers.get(instance);
    if (identifier != null) {
      strongInstances.put(identifier, instance);
    }
    return identifier;
  }

  /**
   * Adds a new instance that was instantiated from Dart.
   *
   * <p>If an instance or identifier has already been added, it will be replaced by the new values.
   * The Dart InstanceManager is considered the source of truth and has the capability to overwrite
   * stored pairs in response to hot restarts.
   *
   * <p>If the manager is closed, the addition is ignored.
   *
   * @param instance the instance to be stored.
   * @param identifier the identifier to be paired with instance. This value must be >= 0.
   */
  public void addDartCreatedInstance(Object instance, long identifier) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return;
    }
    addInstance(instance, identifier);
  }

  /**
   * Adds a new instance that was instantiated from the host platform.
   *
   * @param instance the instance to be stored.
   * @return the unique identifier stored with instance. If the manager is closed, returns -1.
   */
  public long addHostCreatedInstance(Object instance) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return -1;
    }
    final long identifier = nextIdentifier++;
    addInstance(instance, identifier);
    return identifier;
  }

  /**
   * Retrieves the instance associated with identifier.
   *
   * @param identifier the identifier paired to an instance.
   * @param <T> the expected return type.
   * @return the instance associated with `identifier` if the manager contains the value, otherwise
   *     null if the manager doesn't contain the value or the manager is closed.
   */
  @Nullable
  public <T> T getInstance(long identifier) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return null;
    }
    final WeakReference<T> instance = (WeakReference<T>) weakInstances.get(identifier);
    if (instance != null) {
      return instance.get();
    }
    return (T) strongInstances.get(identifier);
  }

  /**
   * Returns whether this manager contains the given `instance`.
   *
   * @param instance the instance whose presence in this manager is to be tested.
   * @return whether this manager contains the given `instance`. If the manager is closed, returns
   *     `false`.
   */
  public boolean containsInstance(Object instance) {
    if (isClosed()) {
      Log.w(TAG, CLOSED_WARNING);
      return false;
    }
    return identifiers.containsKey(instance);
  }

  /**
   * Closes the manager and releases resources.
   *
   * <p>Methods called after this one will be ignored and log a warning.
   */
  public void close() {
    handler.removeCallbacks(this::releaseAllFinalizedInstances);
    isClosed = true;
    identifiers.clear();
    weakInstances.clear();
    strongInstances.clear();
    weakReferencesToIdentifiers.clear();
  }

  /**
   * Whether the manager has released resources and is not longer usable.
   *
   * <p>See {@link #close()}.
   */
  public boolean isClosed() {
    return isClosed;
  }

  private void releaseAllFinalizedInstances() {
    WeakReference<Object> reference;
    while ((reference = (WeakReference<Object>) referenceQueue.poll()) != null) {
      final Long identifier = weakReferencesToIdentifiers.remove(reference);
      if (identifier != null) {
        weakInstances.remove(identifier);
        strongInstances.remove(identifier);
        finalizationListener.onFinalize(identifier);
      }
    }
    handler.postDelayed(
        this::releaseAllFinalizedInstances, CLEAR_FINALIZED_WEAK_REFERENCES_INTERVAL);
  }

  private void addInstance(Object instance, long identifier) {
    if (identifier < 0) {
      throw new IllegalArgumentException("Identifier must be >= 0.");
    }
    final WeakReference<Object> weakReference = new WeakReference<>(instance, referenceQueue);
    identifiers.put(instance, identifier);
    weakInstances.put(identifier, weakReference);
    weakReferencesToIdentifiers.put(weakReference, identifier);
    strongInstances.put(identifier, instance);
  }
}
