package com.airbnb.lottie.network;

import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;

import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.LottieCompositionFactory;
import com.airbnb.lottie.LottieResult;
import com.airbnb.lottie.utils.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipInputStream;

public class NetworkFetcher {

  @NonNull
  private final NetworkCache networkCache;
  @NonNull
  private final LottieNetworkFetcher fetcher;

  public NetworkFetcher(@NonNull NetworkCache networkCache, @NonNull LottieNetworkFetcher fetcher) {
    this.networkCache = networkCache;
    this.fetcher = fetcher;
  }

  @NonNull
  @WorkerThread
  public LottieResult<LottieComposition> fetchSync(@NonNull String url, @Nullable String cacheKey) {
    LottieComposition result = fetchFromCache(url, cacheKey);
    if (result != null) {
      return new LottieResult<>(result);
    }

    Logger.debug("Animation for " + url + " not found in cache. Fetching from network.");

    return fetchFromNetwork(url, cacheKey);
  }

  @Nullable
  @WorkerThread
  private LottieComposition fetchFromCache(@NonNull String url, @Nullable String cacheKey) {
    if (cacheKey == null) {
      return null;
    }
    Pair<FileExtension, InputStream> cacheResult = networkCache.fetch(url);
    if (cacheResult == null) {
      return null;
    }

    FileExtension extension = cacheResult.first;
    InputStream inputStream = cacheResult.second;
    LottieResult<LottieComposition> result;
    if (extension == FileExtension.ZIP) {
      result = LottieCompositionFactory.fromZipStreamSync(new ZipInputStream(inputStream), url);
    } else {
      result = LottieCompositionFactory.fromJsonInputStreamSync(inputStream, url);
    }
    if (result.getValue() != null) {
      return result.getValue();
    }
    return null;
  }

  @NonNull
  @WorkerThread
  private LottieResult<LottieComposition> fetchFromNetwork(@NonNull String url, @Nullable String cacheKey) {
    Logger.debug("Fetching " + url);

    LottieFetchResult fetchResult = null;
    try {
      fetchResult = fetcher.fetchSync(url);
      if (fetchResult.isSuccessful()) {
        InputStream inputStream = fetchResult.bodyByteStream();
        String contentType = fetchResult.contentType();
        LottieResult<LottieComposition> result = fromInputStream(url, inputStream, contentType, cacheKey);
        Logger.debug("Completed fetch from network. Success: " + (result.getValue() != null));
        return result;
      } else {
        return new LottieResult<>(new IllegalArgumentException(fetchResult.error()));
      }
    } catch (Exception e) {
      return new LottieResult<>(e);
    } finally {
      if (fetchResult != null) {
        try {
          fetchResult.close();
        } catch (IOException e) {
          Logger.warning("LottieFetchResult close failed ", e);
        }
      }
    }
  }

  @NonNull
  private LottieResult<LottieComposition> fromInputStream(@NonNull String url, @NonNull InputStream inputStream, @Nullable String contentType,
      @Nullable String cacheKey) throws IOException {
    FileExtension extension;
    LottieResult<LottieComposition> result;
    if (contentType == null) {
      // Assume JSON for best effort parsing. If it fails, it will just deliver the parse exception
      // in the result which is more useful than failing here.
      contentType = "application/json";
    }
    if (contentType.contains("application/zip") ||
        contentType.contains("application/x-zip") ||
        contentType.contains("application/x-zip-compressed") ||
        url.split("\\?")[0].endsWith(".lottie")) {
      Logger.debug("Handling zip response.");
      extension = FileExtension.ZIP;
      result = fromZipStream(url, inputStream, cacheKey);
    } else {
      Logger.debug("Received json response.");
      extension = FileExtension.JSON;
      result = fromJsonStream(url, inputStream, cacheKey);
    }

    if (cacheKey != null && result.getValue() != null) {
      networkCache.renameTempFile(url, extension);
    }

    return result;
  }

  @NonNull
  private LottieResult<LottieComposition> fromZipStream(@NonNull String url, @NonNull InputStream inputStream, @Nullable String cacheKey)
      throws IOException {
    if (cacheKey == null) {
      return LottieCompositionFactory.fromZipStreamSync(new ZipInputStream(inputStream), null);
    }
    File file = networkCache.writeTempCacheFile(url, inputStream, FileExtension.ZIP);
    return LottieCompositionFactory.fromZipStreamSync(new ZipInputStream(new FileInputStream(file)), url);
  }

  @NonNull
  private LottieResult<LottieComposition> fromJsonStream(@NonNull String url, @NonNull InputStream inputStream, @Nullable String cacheKey)
      throws IOException {
    if (cacheKey == null) {
      return LottieCompositionFactory.fromJsonInputStreamSync(inputStream, null);
    }
    File file = networkCache.writeTempCacheFile(url, inputStream, FileExtension.JSON);
    return LottieCompositionFactory.fromJsonInputStreamSync(new FileInputStream(file.getAbsolutePath()), url);
  }
}
