/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.setupdesign;

import static com.google.android.setupcompat.partnerconfig.Util.isNightMode;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings.Global;
import android.provider.Settings.SettingNotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.annotation.StringDef;
import androidx.annotation.VisibleForTesting;
import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.LottieProperty;
import com.airbnb.lottie.SimpleColorFilter;
import com.airbnb.lottie.model.KeyPath;
import com.airbnb.lottie.value.LottieValueCallback;
import com.airbnb.lottie.value.SimpleLottieValueCallback;
import com.google.android.setupcompat.partnerconfig.PartnerConfig;
import com.google.android.setupcompat.partnerconfig.PartnerConfig.ResourceType;
import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
import com.google.android.setupcompat.partnerconfig.ResourceEntry;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.util.BuildCompatUtils;
import com.google.android.setupdesign.lottieloadinglayout.R;
import com.google.android.setupdesign.view.IllustrationVideoView;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A GLIF themed layout with a {@link com.airbnb.lottie.LottieAnimationView} to showing lottie
 * illustration and a substitute {@link com.google.android.setupdesign.view.IllustrationVideoView}
 * to showing mp4 illustration. {@code app:sudIllustrationType} can also be used to specify one of
 * the set including "default", "account", "connection", "update", and "final_hold". {@code
 * app:sudLottieRes} can assign the json file of Lottie resource.
 */
public class GlifLoadingLayout extends GlifLayout {

  private static final String TAG = "GlifLoadingLayout";
  View inflatedView;

  @VisibleForTesting @IllustrationType String illustrationType = IllustrationType.DEFAULT;
  @VisibleForTesting LottieAnimationConfig animationConfig = LottieAnimationConfig.CONFIG_DEFAULT;

  @VisibleForTesting @RawRes int customLottieResource = 0;

  @VisibleForTesting Map<KeyPath, SimpleColorFilter> customizationMap = new HashMap<>();

  @VisibleForTesting
  public List<LottieAnimationFinishListener> animationFinishListeners = new ArrayList<>();

  public GlifLoadingLayout(Context context) {
    this(context, 0, 0);
  }

  public GlifLoadingLayout(Context context, int template) {
    this(context, template, 0);
  }

  public GlifLoadingLayout(Context context, int template, int containerId) {
    super(context, template, containerId);
    init(null, R.attr.sudLayoutTheme);
  }

  public GlifLoadingLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs, R.attr.sudLayoutTheme);
  }

  @TargetApi(VERSION_CODES.HONEYCOMB)
  public GlifLoadingLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(attrs, defStyleAttr);
  }

  private void init(AttributeSet attrs, int defStyleAttr) {
    registerMixin(FooterBarMixin.class, new LoadingFooterBarMixin(this, attrs, defStyleAttr));

    TypedArray a =
        getContext()
            .obtainStyledAttributes(attrs, R.styleable.SudGlifLoadingLayout, defStyleAttr, 0);
    customLottieResource = a.getResourceId(R.styleable.SudGlifLoadingLayout_sudLottieRes, 0);
    String illustrationType = a.getString(R.styleable.SudGlifLoadingLayout_sudIllustrationType);
    boolean usePartnerHeavyTheme =
        a.getBoolean(R.styleable.SudGlifLoadingLayout_sudUsePartnerHeavyTheme, false);
    a.recycle();

    if (customLottieResource != 0) {
      inflateLottieView();
      ViewGroup container = findContainer(0);
      container.setVisibility(View.VISIBLE);
    } else {
      if (illustrationType != null) {
        setIllustrationType(illustrationType);
      }

      if (BuildCompatUtils.isAtLeastS()) {
        inflateLottieView();
      } else {
        inflateIllustrationStub();
      }
    }

    boolean applyPartnerHeavyThemeResource = shouldApplyPartnerResource() && usePartnerHeavyTheme;
    if (applyPartnerHeavyThemeResource) {
      View view = findManagedViewById(R.id.sud_layout_loading_content);
      if (view != null) {
        applyPartnerCustomizationContentPaddingTopStyle(view);
      }
    }

    updateHeaderHeight();
    updateLandscapeMiddleHorizontalSpacing();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (inflatedView instanceof LinearLayout) {
      updateContentPadding((LinearLayout) inflatedView);
    }
  }

  public void setIllustrationType(@IllustrationType String type) {
    if (customLottieResource != 0) {
      throw new IllegalStateException(
          "custom illustration already applied, should not set illustration.");
    }

    if (!illustrationType.equals(type)) {
      illustrationType = type;
      customizationMap.clear();
    }

    switch (type) {
      case IllustrationType.ACCOUNT:
        animationConfig = LottieAnimationConfig.CONFIG_ACCOUNT;
        break;

      case IllustrationType.CONNECTION:
        animationConfig = LottieAnimationConfig.CONFIG_CONNECTION;
        break;

      case IllustrationType.UPDATE:
        animationConfig = LottieAnimationConfig.CONFIG_UPDATE;
        break;

      case IllustrationType.FINAL_HOLD:
        animationConfig = LottieAnimationConfig.CONFIG_FINAL_HOLD;
        break;

      default:
        animationConfig = LottieAnimationConfig.CONFIG_DEFAULT;
        break;
    }

    updateAnimationView();
  }

  // TODO: [GlifLoadingLayout] Should add testcase. LottieAnimationView was auto
  // generated not able to mock. So we have no idea how to detected is the api pass to
  // LottiAnimationView correctly.
  public boolean setAnimation(InputStream inputStream, String keyCache) {
    LottieAnimationView lottieAnimationView = findLottieAnimationView();
    if (lottieAnimationView != null) {
      lottieAnimationView.setAnimation(inputStream, keyCache);
      return true;
    } else {
      return false;
    }
  }

  public boolean setAnimation(String assetName) {
    LottieAnimationView lottieAnimationView = findLottieAnimationView();
    if (lottieAnimationView != null) {
      lottieAnimationView.setAnimation(assetName);
      return true;
    } else {
      return false;
    }
  }

  public boolean setAnimation(@RawRes int rawRes) {
    LottieAnimationView lottieAnimationView = findLottieAnimationView();
    if (lottieAnimationView != null) {
      lottieAnimationView.setAnimation(rawRes);
      return true;
    } else {
      return false;
    }
  }

  private void updateAnimationView() {
    if (BuildCompatUtils.isAtLeastS()) {
      setLottieResource();
    } else {
      setIllustrationResource();
    }
  }

  /**
   * Call this when your activity is done and should be closed. The activity will be finished while
   * animation finished.
   */
  public void finish(@NonNull Activity activity) {
    if (activity == null) {
      throw new NullPointerException("activity should not be null");
    }
    registerAnimationFinishRunnable(activity::finish, /* allowFinishWithMaximumDuration= */ true);
  }

  /**
   * Launch a new activity after the animation finished.
   *
   * @param activity The activity which is GlifLoadingLayout attached to.
   * @param intent The intent to start.
   * @param options Additional options for how the Activity should be started. See {@link
   *     android.content.Context#startActivity(Intent, Bundle)} for more details.
   * @param finish Finish the activity after startActivity
   * @see Activity#startActivity(Intent)
   * @see Activity#startActivityForResult
   */
  public void startActivity(
      @NonNull Activity activity,
      @NonNull Intent intent,
      @Nullable Bundle options,
      boolean finish) {
    if (activity == null) {
      throw new NullPointerException("activity should not be null");
    }

    if (intent == null) {
      throw new NullPointerException("intent should not be null");
    }

    registerAnimationFinishRunnable(
        () -> {
          if (options == null || Build.VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN) {
            activity.startActivity(intent);
          } else {
            activity.startActivity(intent, options);
          }

          if (finish) {
            activity.finish();
          }
        },
        /* allowFinishWithMaximumDuration= */ true);
  }

  /**
   * Waiting for the animation finished and launch an activity for which you would like a result
   * when it finished.
   *
   * @param activity The activity which the GlifLoadingLayout attached to.
   * @param intent The intent to start.
   * @param requestCode If >= 0, this code will be returned in onActivityResult() when the activity
   *     exits.
   * @param options Additional options for how the Activity should be started.
   * @param finish Finish the activity after startActivityForResult. The onActivityResult might not
   *     be called because the activity already finished.
   *     <p>See {@link android.content.Context#startActivity(Intent, Bundle)}
   *     Context.startActivity(Intent, Bundle)} for more details.
   */
  public void startActivityForResult(
      @NonNull Activity activity,
      @NonNull Intent intent,
      int requestCode,
      @Nullable Bundle options,
      boolean finish) {
    if (activity == null) {
      throw new NullPointerException("activity should not be null");
    }

    if (intent == null) {
      throw new NullPointerException("intent should not be null");
    }

    registerAnimationFinishRunnable(
        () -> {
          if (options == null || Build.VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN) {
            activity.startActivityForResult(intent, requestCode);
          } else {
            activity.startActivityForResult(intent, requestCode, options);
          }

          if (finish) {
            activity.finish();
          }
        },
        /* allowFinishWithMaximumDuration= */ true);
  }

  private void updateHeaderHeight() {
    View headerView = findManagedViewById(R.id.sud_header_scroll_view);
    if (headerView != null
        && PartnerConfigHelper.get(getContext())
            .isPartnerConfigAvailable(PartnerConfig.CONFIG_LOADING_LAYOUT_HEADER_HEIGHT)) {
      float configHeaderHeight =
          PartnerConfigHelper.get(getContext())
              .getDimension(getContext(), PartnerConfig.CONFIG_LOADING_LAYOUT_HEADER_HEIGHT);
      headerView.getLayoutParams().height = (int) configHeaderHeight;
    }
  }

  private void updateContentPadding(LinearLayout linearLayout) {
    int paddingTop = linearLayout.getPaddingTop();
    int paddingLeft = linearLayout.getPaddingLeft();
    int paddingRight = linearLayout.getPaddingRight();
    int paddingBottom = linearLayout.getPaddingBottom();

    if (PartnerConfigHelper.get(getContext())
        .isPartnerConfigAvailable(PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_TOP)) {
      float configPaddingTop =
          PartnerConfigHelper.get(getContext())
              .getDimension(getContext(), PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_TOP);
      if (configPaddingTop >= 0) {
        paddingTop = (int) configPaddingTop;
      }
    }

    if (PartnerConfigHelper.get(getContext())
        .isPartnerConfigAvailable(PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_START)) {
      float configPaddingLeft =
          PartnerConfigHelper.get(getContext())
              .getDimension(getContext(), PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_START);
      if (configPaddingLeft >= 0) {
        paddingLeft = (int) configPaddingLeft;
      }
    }

    if (PartnerConfigHelper.get(getContext())
        .isPartnerConfigAvailable(PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_END)) {
      float configPaddingRight =
          PartnerConfigHelper.get(getContext())
              .getDimension(getContext(), PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_END);
      if (configPaddingRight >= 0) {
        paddingRight = (int) configPaddingRight;
      }
    }

    if (PartnerConfigHelper.get(getContext())
        .isPartnerConfigAvailable(PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_BOTTOM)) {
      float configPaddingBottom =
          PartnerConfigHelper.get(getContext())
              .getDimension(getContext(), PartnerConfig.CONFIG_LOADING_LAYOUT_PADDING_BOTTOM);
      if (configPaddingBottom >= 0) {
        FooterBarMixin footerBarMixin = getMixin(FooterBarMixin.class);
        if (footerBarMixin == null || footerBarMixin.getButtonContainer() == null) {
          paddingBottom = (int) configPaddingBottom;
        } else {
          paddingBottom =
              (int) configPaddingBottom
                  - (int)
                      Math.min(
                          configPaddingBottom,
                          getButtonContainerHeight(footerBarMixin.getButtonContainer()));
        }
      }
    }

    linearLayout.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
  }

  private static final int getButtonContainerHeight(View view) {
    view.measure(
        MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), MeasureSpec.EXACTLY));
    return view.getMeasuredHeight();
  }

  private void inflateLottieView() {
    final View lottieLayout = peekLottieLayout();
    if (lottieLayout == null) {
      ViewStub viewStub = findManagedViewById(R.id.sud_loading_layout_lottie_stub);
      if (viewStub != null) {
        inflatedView = viewStub.inflate();
        if (inflatedView instanceof LinearLayout) {
          updateContentPadding((LinearLayout) inflatedView);
        }
        setLottieResource();
      }
    }
  }

  private void inflateIllustrationStub() {
    final View progressLayout = peekProgressIllustrationLayout();
    if (progressLayout == null) {
      ViewStub viewStub = findManagedViewById(R.id.sud_loading_layout_illustration_stub);
      if (viewStub != null) {
        inflatedView = viewStub.inflate();
        if (inflatedView instanceof LinearLayout) {
          updateContentPadding((LinearLayout) inflatedView);
        }
        setIllustrationResource();
      }
    }
  }

  private void setLottieResource() {
    LottieAnimationView lottieView = findViewById(R.id.sud_lottie_view);
    if (lottieView == null) {
      Log.w(TAG, "Lottie view not found, skip set resource. Wait for layout inflated.");
      return;
    }
    if (customLottieResource != 0) {
      InputStream inputRaw = getResources().openRawResource(customLottieResource);
      lottieView.setAnimation(inputRaw, null);
      lottieView.playAnimation();
    } else {
      PartnerConfigHelper partnerConfigHelper = PartnerConfigHelper.get(getContext());
      ResourceEntry resourceEntry =
          partnerConfigHelper.getIllustrationResourceEntry(
              getContext(), animationConfig.getLottieConfig());

      if (resourceEntry != null) {
        InputStream inputRaw =
            resourceEntry.getResources().openRawResource(resourceEntry.getResourceId());
        lottieView.setAnimation(inputRaw, null);
        lottieView.playAnimation();
        setLottieLayoutVisibility(View.VISIBLE);
        setIllustrationLayoutVisibility(View.GONE);
        applyThemeCustomization();
      } else {
        setLottieLayoutVisibility(View.GONE);
        setIllustrationLayoutVisibility(View.VISIBLE);
        inflateIllustrationStub();
      }
    }
  }

  private void setIllustrationLayoutVisibility(int visibility) {
    View illustrationLayout = findViewById(R.id.sud_layout_progress_illustration);
    if (illustrationLayout != null) {
      illustrationLayout.setVisibility(visibility);
    }
  }

  private void setLottieLayoutVisibility(int visibility) {
    View lottieLayout = findViewById(R.id.sud_layout_lottie_illustration);
    if (lottieLayout != null) {
      lottieLayout.setVisibility(visibility);
    }
  }

  @VisibleForTesting
  boolean isLottieLayoutVisible() {
    View lottieLayout = findViewById(R.id.sud_layout_lottie_illustration);
    return lottieLayout != null && lottieLayout.getVisibility() == View.VISIBLE;
  }

  private void setIllustrationResource() {
    View illustrationLayout = findViewById(R.id.sud_layout_progress_illustration);
    if (illustrationLayout == null) {
      Log.i(TAG, "Illustration stub not inflated, skip set resource");
      return;
    }

    IllustrationVideoView illustrationVideoView =
        findManagedViewById(R.id.sud_progress_illustration);
    ProgressBar progressBar = findManagedViewById(R.id.sud_progress_bar);

    PartnerConfigHelper partnerConfigHelper = PartnerConfigHelper.get(getContext());
    ResourceEntry resourceEntry =
        partnerConfigHelper.getIllustrationResourceEntry(
            getContext(), animationConfig.getIllustrationConfig());

    if (resourceEntry != null) {
      progressBar.setVisibility(GONE);
      illustrationVideoView.setVisibility(VISIBLE);
      illustrationVideoView.setVideoResourceEntry(resourceEntry);
    } else {
      progressBar.setVisibility(VISIBLE);
      illustrationVideoView.setVisibility(GONE);
    }
  }

  private LottieAnimationView findLottieAnimationView() {
    return findViewById(R.id.sud_lottie_view);
  }

  private IllustrationVideoView findIllustrationVideoView() {
    return findManagedViewById(R.id.sud_progress_illustration);
  }

  public void playAnimation() {
    LottieAnimationView lottieAnimationView = findLottieAnimationView();
    if (lottieAnimationView != null) {
      lottieAnimationView.setRepeatCount(LottieDrawable.INFINITE);
      lottieAnimationView.playAnimation();
    }
  }

  /** Returns whether the layout is waiting for animation finish or not. */
  public boolean isFinishing() {
    LottieAnimationView lottieAnimationView = findLottieAnimationView();
    if (lottieAnimationView != null) {
      return !animationFinishListeners.isEmpty() && lottieAnimationView.getRepeatCount() == 0;
    } else {
      return false;
    }
  }

  @AnimationType
  public int getAnimationType() {
    if (findLottieAnimationView() != null && isLottieLayoutVisible()) {
      return AnimationType.LOTTIE;
    } else if (findIllustrationVideoView() != null) {
      return AnimationType.ILLUSTRATION;
    } else {
      return AnimationType.PROGRESS_BAR;
    }
  }

  // TODO: Should add testcase with mocked LottieAnimationView.
  /** Add an animator listener to {@link LottieAnimationView}. */
  public void addAnimatorListener(Animator.AnimatorListener listener) {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      animationView.addAnimatorListener(listener);
    }
  }

  /** Remove the listener from {@link LottieAnimationView}. */
  public void removeAnimatorListener(AnimatorListener listener) {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      animationView.removeAnimatorListener(listener);
    }
  }

  /** Remove all {@link AnimatorListener} from {@link LottieAnimationView}. */
  public void removeAllAnimatorListener() {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      animationView.removeAllAnimatorListeners();
    }
  }

  /** Add a value callback with property {@link LottieProperty.COLOR_FILTER}. */
  public void addColorCallback(KeyPath keyPath, LottieValueCallback<ColorFilter> callback) {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback);
    }
  }

  /** Add a simple value callback with property {@link LottieProperty.COLOR_FILTER}. */
  public void addColorCallback(KeyPath keyPath, SimpleLottieValueCallback<ColorFilter> callback) {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback);
    }
  }

  @VisibleForTesting
  protected void loadCustomization() {
    if (customizationMap.isEmpty()) {
      PartnerConfigHelper helper = PartnerConfigHelper.get(getContext());
      List<String> lists =
          helper.getStringArray(
              getContext(),
              isNightMode(getResources().getConfiguration())
                  ? animationConfig.getDarkThemeCustomization()
                  : animationConfig.getLightThemeCustomization());
      for (String item : lists) {
        String[] splitItem = item.split(":");
        if (splitItem.length == 2) {
          customizationMap.put(
              new KeyPath(splitItem[0]), new SimpleColorFilter(Color.parseColor(splitItem[1])));
        } else {
          Log.w(TAG, "incorrect format customization, value=" + item);
        }
      }
    }
  }

  @VisibleForTesting
  protected void applyThemeCustomization() {
    LottieAnimationView animationView = findLottieAnimationView();
    if (animationView != null) {
      loadCustomization();
      for (KeyPath keyPath : customizationMap.keySet()) {
        animationView.addValueCallback(
            keyPath,
            LottieProperty.COLOR_FILTER,
            new LottieValueCallback<>(customizationMap.get(keyPath)));
      }
    }
  }

  @Nullable
  private View peekLottieLayout() {
    return findViewById(R.id.sud_layout_lottie_illustration);
  }

  @Nullable
  private View peekProgressIllustrationLayout() {
    return findViewById(R.id.sud_layout_progress_illustration);
  }

  @Override
  protected View onInflateTemplate(LayoutInflater inflater, int template) {
    if (template == 0) {
      template = R.layout.sud_glif_loading_template;
    }
    return inflateTemplate(inflater, R.style.SudThemeGlif_Light, template);
  }

  @Override
  protected ViewGroup findContainer(int containerId) {
    if (containerId == 0) {
      containerId = R.id.sud_layout_content;
    }
    return super.findContainer(containerId);
  }

  /** The progress config used to maps to different animation */
  public enum LottieAnimationConfig {
    CONFIG_DEFAULT(
        PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_DEFAULT,
        PartnerConfig.CONFIG_LOADING_LOTTIE_DEFAULT,
        PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_DEFAULT,
        PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_DEFAULT),
    CONFIG_ACCOUNT(
        PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_ACCOUNT,
        PartnerConfig.CONFIG_LOADING_LOTTIE_ACCOUNT,
        PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_ACCOUNT,
        PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_ACCOUNT),
    CONFIG_CONNECTION(
        PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_CONNECTION,
        PartnerConfig.CONFIG_LOADING_LOTTIE_CONNECTION,
        PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_CONNECTION,
        PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_CONNECTION),
    CONFIG_UPDATE(
        PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_UPDATE,
        PartnerConfig.CONFIG_LOADING_LOTTIE_UPDATE,
        PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_UPDATE,
        PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_UPDATE),
    CONFIG_FINAL_HOLD(
        PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_FINAL_HOLD,
        PartnerConfig.CONFIG_LOADING_LOTTIE_FINAL_HOLD,
        PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_FINAL_HOLD,
        PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_FINAL_HOLD);

    private final PartnerConfig illustrationConfig;
    private final PartnerConfig lottieConfig;
    private final PartnerConfig lightThemeCustomization;
    private final PartnerConfig darkThemeCustomization;

    LottieAnimationConfig(
        PartnerConfig illustrationConfig,
        PartnerConfig lottieConfig,
        PartnerConfig lightThemeCustomization,
        PartnerConfig darkThemeCustomization) {
      if (illustrationConfig.getResourceType() != ResourceType.ILLUSTRATION
          || lottieConfig.getResourceType() != ResourceType.ILLUSTRATION) {
        throw new IllegalArgumentException(
            "Illustration progress only allow illustration resource");
      }
      this.illustrationConfig = illustrationConfig;
      this.lottieConfig = lottieConfig;
      this.lightThemeCustomization = lightThemeCustomization;
      this.darkThemeCustomization = darkThemeCustomization;
    }

    PartnerConfig getIllustrationConfig() {
      return illustrationConfig;
    }

    PartnerConfig getLottieConfig() {
      return lottieConfig;
    }

    PartnerConfig getLightThemeCustomization() {
      return lightThemeCustomization;
    }

    PartnerConfig getDarkThemeCustomization() {
      return darkThemeCustomization;
    }
  }

  /**
   * Register the {@link Runnable} as a callback class that will be perform when animation finished.
   */
  public void registerAnimationFinishRunnable(Runnable runnable) {
    registerAnimationFinishRunnable(runnable, /* allowFinishWithMaximumDuration= */ false);
  }

  /**
   * Register the {@link Runnable} as a callback class that will be perform when animation finished.
   * {@code allowFinishWithMaximumDuration} to allow the animation finish advanced by {@link
   * PartnerConfig#CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS} config. The {@code runnable}
   * will be performed if the Lottie animation finish played and the duration of Lottie animation
   * less than @link PartnerConfig#CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS} config.
   */
  public void registerAnimationFinishRunnable(
      Runnable runnable, boolean allowFinishWithMaximumDuration) {
    if (allowFinishWithMaximumDuration) {
      int delayMs =
          PartnerConfigHelper.get(getContext())
              .getInteger(
                  getContext(), PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS, 0);
      animationFinishListeners.add(new LottieAnimationFinishListener(this, runnable, delayMs));
    } else {
      animationFinishListeners.add(
          new LottieAnimationFinishListener(this, runnable, /* finishWithMinimumDuration= */ 0L));
    }
  }

  /** The listener that to indicate the playing status for lottie animation. */
  @VisibleForTesting
  public static class LottieAnimationFinishListener {

    private final Handler handler;
    private final Runnable runnable;
    private final GlifLoadingLayout glifLoadingLayout;
    private final LottieAnimationView lottieAnimationView;

    @VisibleForTesting
    AnimatorListener animatorListener =
        new AnimatorListener() {
          @Override
          public void onAnimationStart(Animator animation) {
            // Do nothing.
          }

          @Override
          public void onAnimationEnd(Animator animation) {
            onAnimationFinished();
          }

          @Override
          public void onAnimationCancel(Animator animation) {
            // Do nothing.
          }

          @Override
          public void onAnimationRepeat(Animator animation) {
            // Do nothing.
          }
        };

    @VisibleForTesting
    LottieAnimationFinishListener(
        GlifLoadingLayout glifLoadingLayout, Runnable runnable, long finishWithMinimumDuration) {
      if (runnable == null) {
        throw new NullPointerException("Runnable can not be null");
      }
      this.glifLoadingLayout = glifLoadingLayout;
      this.runnable = runnable;
      this.handler = new Handler(Looper.getMainLooper());
      this.lottieAnimationView = glifLoadingLayout.findLottieAnimationView();

      if (glifLoadingLayout.isLottieLayoutVisible() && !isZeroAnimatorDurationScale()) {
        lottieAnimationView.setRepeatCount(0);
        lottieAnimationView.addAnimatorListener(animatorListener);
        if (finishWithMinimumDuration > 0) {
          handler.postDelayed(this::onAnimationFinished, finishWithMinimumDuration);
        }
      } else {
        onAnimationFinished();
      }
    }

    @VisibleForTesting
    boolean isZeroAnimatorDurationScale() {
      try {
        if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
          return Global.getFloat(
              glifLoadingLayout.getContext().getContentResolver(), Global.ANIMATOR_DURATION_SCALE)
              == 0f;
        } else {
          return false;
        }

      } catch (SettingNotFoundException e) {
        return false;
      }
    }

    @VisibleForTesting
    public void onAnimationFinished() {
      handler.removeCallbacks(runnable);
      runnable.run();
      if (lottieAnimationView != null) {
        lottieAnimationView.removeAnimatorListener(animatorListener);
      }
      glifLoadingLayout.animationFinishListeners.remove(this);
    }
  }

  /** Annotates the state for the illustration. */
  @Retention(RetentionPolicy.SOURCE)
  @StringDef({
    IllustrationType.ACCOUNT,
    IllustrationType.CONNECTION,
    IllustrationType.DEFAULT,
    IllustrationType.UPDATE,
    IllustrationType.FINAL_HOLD
  })
  public @interface IllustrationType {
    String DEFAULT = "default";
    String ACCOUNT = "account";
    String CONNECTION = "connection";
    String UPDATE = "update";
    String FINAL_HOLD = "final_hold";
  }

  /** Annotates the type for the illustration. */
  @Retention(RetentionPolicy.SOURCE)
  @IntDef({AnimationType.LOTTIE, AnimationType.ILLUSTRATION, AnimationType.PROGRESS_BAR})
  public @interface AnimationType {
    int LOTTIE = 1;
    int ILLUSTRATION = 2;
    int PROGRESS_BAR = 3;
  }
}
