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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager;
import io.flutter.embedding.engine.loader.FlutterLoader;

/**
 * This class is a simple dependency injector for the relatively thin Android part of the Flutter
 * engine.
 *
 * <p>This simple solution is used facilitate testability without bringing in heavier
 * app-development centric dependency injection frameworks such as Guice or Dagger2 or spreading
 * construction injection everywhere.
 */
public final class FlutterInjector {

  private static FlutterInjector instance;
  private static boolean accessed;

  /**
   * Use {@link FlutterInjector.Builder} to specify members to be injected via the static {@code
   * FlutterInjector}.
   *
   * <p>This can only be called at the beginning of the program before the {@link #instance()} is
   * accessed.
   */
  @VisibleForTesting
  public static void setInstance(@NonNull FlutterInjector injector) {
    if (accessed) {
      throw new IllegalStateException(
          "Cannot change the FlutterInjector instance once it's been "
              + "read. If you're trying to dependency inject, be sure to do so at the beginning of "
              + "the program");
    }
    instance = injector;
  }

  /**
   * Retrieve the static instance of the {@code FlutterInjector} to use in your program.
   *
   * <p>Once you access it, you can no longer change the values injected.
   *
   * <p>If no override is provided for the injector, reasonable defaults are provided.
   */
  public static FlutterInjector instance() {
    accessed = true;
    if (instance == null) {
      instance = new Builder().build();
    }
    return instance;
  }

  // This whole class is here to enable testing so to test the thing that lets you test, some degree
  // of hack is needed.
  @VisibleForTesting
  public static void reset() {
    accessed = false;
    instance = null;
  }

  private FlutterInjector(
      @NonNull FlutterLoader flutterLoader,
      @Nullable DeferredComponentManager deferredComponentManager,
      @NonNull FlutterJNI.Factory flutterJniFactory) {
    this.flutterLoader = flutterLoader;
    this.deferredComponentManager = deferredComponentManager;
    this.flutterJniFactory = flutterJniFactory;
  }

  private FlutterLoader flutterLoader;
  private DeferredComponentManager deferredComponentManager;
  private FlutterJNI.Factory flutterJniFactory;

  /** Returns the {@link FlutterLoader} instance to use for the Flutter Android engine embedding. */
  @NonNull
  public FlutterLoader flutterLoader() {
    return flutterLoader;
  }

  /**
   * Returns the {@link DeferredComponentManager} instance to use for the Flutter Android engine
   * embedding.
   */
  @Nullable
  public DeferredComponentManager deferredComponentManager() {
    return deferredComponentManager;
  }

  @NonNull
  public FlutterJNI.Factory getFlutterJNIFactory() {
    return flutterJniFactory;
  }

  /**
   * Builder used to supply a custom FlutterInjector instance to {@link
   * FlutterInjector#setInstance(FlutterInjector)}.
   *
   * <p>Non-overridden values have reasonable defaults.
   */
  public static final class Builder {
    private FlutterLoader flutterLoader;
    private DeferredComponentManager deferredComponentManager;
    private FlutterJNI.Factory flutterJniFactory;
    /**
     * Sets a {@link FlutterLoader} override.
     *
     * <p>A reasonable default will be used if unspecified.
     */
    public Builder setFlutterLoader(@NonNull FlutterLoader flutterLoader) {
      this.flutterLoader = flutterLoader;
      return this;
    }

    public Builder setDeferredComponentManager(
        @Nullable DeferredComponentManager deferredComponentManager) {
      this.deferredComponentManager = deferredComponentManager;
      return this;
    }

    public Builder setFlutterJNIFactory(@NonNull FlutterJNI.Factory factory) {
      this.flutterJniFactory = factory;
      return this;
    }

    private void fillDefaults() {
      if (flutterJniFactory == null) {
        flutterJniFactory = new FlutterJNI.Factory();
      }

      if (flutterLoader == null) {
        flutterLoader = new FlutterLoader(flutterJniFactory.provideFlutterJNI());
      }
      // DeferredComponentManager's intended default is null.
    }

    /**
     * Builds a {@link FlutterInjector} from the builder. Unspecified properties will have
     * reasonable defaults.
     */
    public FlutterInjector build() {
      fillDefaults();

      return new FlutterInjector(flutterLoader, deferredComponentManager, flutterJniFactory);
    }
  }
}
