/*
 * Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.gnd.system;

import android.graphics.Bitmap;
import android.util.Log;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.inject.Inject;
import javax.inject.Singleton;

@Singleton
public class MediaUploadManager {

  private static final String TAG = MediaUploadManager.class.getName();
  private static final String MEDIA_ROOT_DIR = "uploaded_media";
  private final SimpleDateFormat DATE_FORMAT =
      new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());

  @Inject
  MediaUploadManager() {}

  /** Returns a reference to the default Storage bucket. */
  private FirebaseStorage getStorage() {
    return FirebaseStorage.getInstance();
  }

  /** Returns a reference to the root media dir. */
  private StorageReference getRootMediaDir() {
    return getStorage().getReference().child(MEDIA_ROOT_DIR);
  }

  /**
   * Returns a reference to a object under the root media dir.
   *
   * @param fileName Name of the uploaded media
   */
  private StorageReference createReference(String fileName) {
    return getRootMediaDir().child(fileName + '-' + getFilenameSuffix());
  }

  /** Converts current timestamp to a string to be used a suffix for uploading media. */
  private String getFilenameSuffix() {
    return DATE_FORMAT.format(new Date());
  }

  public void uploadMedia(Bitmap bitmap, String fileName) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] data = baos.toByteArray();

    uploadTask(createReference(fileName).putBytes(data), fileName);
  }

  private void uploadTask(UploadTask uploadTask, String fileName) {
    uploadTask
        .addOnCanceledListener(
            () -> {
              Log.d(TAG, String.format("Uploading canceled: %s", fileName));
            })
        .addOnCompleteListener(
            task -> {
              Log.d(TAG, String.format("Uploading completed: %s", fileName));
            })
        .addOnFailureListener(
            e -> {
              Log.d(TAG, String.format("Uploading failed: %s", fileName), e);
            })
        .addOnSuccessListener(
            taskSnapshot -> {
              Log.d(TAG, String.format("Uploading succeeded: %s", fileName));
            })
        .addOnProgressListener(
            taskSnapshot -> {
              double percentCompleted =
                  100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount();
              Log.d(TAG, String.format("Uploading in progress: %s %f", fileName, percentCompleted));
            });
  }
}

@@ -661,16 +661,40 @@
 Bitmap;%0A
+import android.net.Uri;%0A
 import a
@@ -900,16 +900,37 @@
 Stream;%0A
+import java.io.File;%0A
 import j
@@ -2183,16 +2183,152 @@
 oadMedia
+FromFile(File file, String fileName) %7B%0A    runTask(createUploadTask(fileName, file), fileName);%0A  %7D%0A%0A  public void uploadMediaFromBitmap
 (Bitmap 
@@ -2523,69 +2523,327 @@
     
-uploadTask(createReference(fileName).putBytes(data), fileName
+runTask(createUploadTask(fileName, data), fileName);%0A  %7D%0A%0A  private UploadTask createUploadTask(String fileName, byte%5B%5D bytes) %7B%0A    return createReference(fileName).putBytes(bytes);%0A  %7D%0A%0A  private UploadTask createUploadTask(String fileName, File file) %7B%0A    return createReference(fileName).putFile(Uri.fromFile(file)
 );%0A 
@@ -2861,22 +2861,19 @@
 te void 
-upload
+run
 Task(Upl

Add overloaded methods for uploading via File