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.utils.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Helper class to save and restore animations fetched from an URL to the app disk cache.
 */
public class NetworkCache {

  @NonNull
  private final LottieNetworkCacheProvider cacheProvider;

  public NetworkCache(@NonNull LottieNetworkCacheProvider cacheProvider) {
    this.cacheProvider = cacheProvider;
  }

  public void clear() {
    File parentDir = parentDir();
    if (parentDir.exists()) {
      File[] files = parentDir.listFiles();
      if (files != null && files.length > 0) {
        for (File file : parentDir.listFiles()) {
          file.delete();
        }
      }
      parentDir.delete();
    }
  }

  /**
   * If the animation doesn't exist in the cache, null will be returned.
   * <p>
   * Once the animation is successfully parsed, {@link #renameTempFile(String, FileExtension)} must be
   * called to move the file from a temporary location to its permanent cache location so it can
   * be used in the future.
   */
  @Nullable
  @WorkerThread
  Pair<FileExtension, InputStream> fetch(String url) {
    File cachedFile;
    try {
      cachedFile = getCachedFile(url);
    } catch (FileNotFoundException e) {
      return null;
    }
    if (cachedFile == null) {
      return null;
    }

    FileInputStream inputStream;
    try {
      inputStream = new FileInputStream(cachedFile);
    } catch (FileNotFoundException e) {
      return null;
    }

    FileExtension extension;
    if (cachedFile.getAbsolutePath().endsWith(".zip")) {
      extension = FileExtension.ZIP;
    } else {
      extension = FileExtension.JSON;
    }

    Logger.debug("Cache hit for " + url + " at " + cachedFile.getAbsolutePath());
    return new Pair<>(extension, (InputStream) inputStream);
  }

  /**
   * Writes an InputStream from a network response to a temporary file. If the file successfully parses
   * to an composition, {@link #renameTempFile(String, FileExtension)} should be called to move the file
   * to its final location for future cache hits.
   */
  File writeTempCacheFile(String url, InputStream stream, FileExtension extension) throws IOException {
    String fileName = filenameForUrl(url, extension, true);
    File file = new File(parentDir(), fileName);
    try {
      OutputStream output = new FileOutputStream(file);
      //noinspection TryFinallyCanBeTryWithResources
      try {
        byte[] buffer = new byte[1024];
        int read;

        while ((read = stream.read(buffer)) != -1) {
          output.write(buffer, 0, read);
        }

        output.flush();
      } finally {
        output.close();
      }
    } finally {
      stream.close();
    }
    return file;
  }

  /**
   * If the file created by {@link #writeTempCacheFile(String, InputStream, FileExtension)} was successfully parsed,
   * this should be called to remove the temporary part of its name which will allow it to be a cache hit in the future.
   */
  void renameTempFile(String url, FileExtension extension) {
    String fileName = filenameForUrl(url, extension, true);
    File file = new File(parentDir(), fileName);
    String newFileName = file.getAbsolutePath().replace(".temp", "");
    File newFile = new File(newFileName);
    boolean renamed = file.renameTo(newFile);
    Logger.debug("Copying temp file to real file (" + newFile + ")");
    if (!renamed) {
      Logger.warning("Unable to rename cache file " + file.getAbsolutePath() + " to " + newFile.getAbsolutePath() + ".");
    }
  }

  /**
   * Returns the cache file for the given url if it exists. Checks for both json and zip.
   * Returns null if neither exist.
   */
  @Nullable
  private File getCachedFile(String url) throws FileNotFoundException {
    File jsonFile = new File(parentDir(), filenameForUrl(url, FileExtension.JSON, false));
    if (jsonFile.exists()) {
      return jsonFile;
    }
    File zipFile = new File(parentDir(), filenameForUrl(url, FileExtension.ZIP, false));
    if (zipFile.exists()) {
      return zipFile;
    }
    return null;
  }

  private File parentDir() {
    File file = cacheProvider.getCacheDir();
    if (file.isFile()) {
      file.delete();
    }
    if (!file.exists()) {
      file.mkdirs();
    }
    return file;
  }

  private static String filenameForUrl(String url, FileExtension extension, boolean isTemp) {
    return "lottie_cache_" + url.replaceAll("\\W+", "") + (isTemp ? extension.tempExtension() : extension.extension);
  }
}
