/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;


import com.googlecode.android_scripting.IoUtils;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.exception.Sl4aException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * AsyncTask for extracting ZIP files.
 *
 * @author Damon Kohler (damonkohler@gmail.com)
 * @author Alexey Reznichenko (alexey.reznichenko@gmail.com)
 */
public class UrlDownloaderTask extends AsyncTask<Void, Integer, Long> {

  private final URL mUrl;
  private final File mFile;
  private final ProgressDialog mDialog;

  private Throwable mException;
  private OutputStream mProgressReportingOutputStream;

  private final class ProgressReportingOutputStream extends FileOutputStream {
    private int mProgress = 0;

    private ProgressReportingOutputStream(File f) throws FileNotFoundException {
      super(f);
    }

    @Override
    public void write(byte[] buffer, int offset, int count) throws IOException {
      super.write(buffer, offset, count);
      mProgress += count;
      publishProgress(mProgress);
    }
  }

  public UrlDownloaderTask(String url, String out, Context context) throws MalformedURLException {
    super();
    if (context != null) {
      mDialog = new ProgressDialog(context);
    } else {
      mDialog = null;
    }
    mUrl = new URL(url);
    String fileName = new File(mUrl.getFile()).getName();
    mFile = new File(out, fileName);
  }

  @Override
  protected void onPreExecute() {
    Log.v("Downloading " + mUrl);
    if (mDialog != null) {
      mDialog.setTitle("Downloading");
      mDialog.setMessage(mFile.getName());
      // mDialog.setIndeterminate(true);
      mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
          cancel(true);
        }
      });
      mDialog.show();
    }
  }

  @Override
  protected Long doInBackground(Void... params) {
    try {
      return download();
    } catch (Exception e) {
      if (mFile.exists()) {
        // Clean up bad downloads.
        mFile.delete();
      }
      mException = e;
      return null;
    }
  }

  @Override
  protected void onProgressUpdate(Integer... progress) {
    if (mDialog == null) {
      return;
    }
    if (progress.length > 1) {
      int contentLength = progress[1];
      if (contentLength == -1) {
        mDialog.setIndeterminate(true);
      } else {
        mDialog.setMax(contentLength);
      }
    } else {
      mDialog.setProgress(progress[0].intValue());
    }
  }

  @Override
  protected void onPostExecute(Long result) {
    if (mDialog != null && mDialog.isShowing()) {
      mDialog.dismiss();
    }
    if (isCancelled()) {
      return;
    }
    if (mException != null) {
      Log.e("Download failed.", mException);
    }
  }

  @Override
  protected void onCancelled() {
    if (mDialog != null) {
      mDialog.setTitle("Download cancelled.");
    }
  }

  private long download() throws Exception {
    URLConnection connection = null;
    try {
      connection = mUrl.openConnection();
    } catch (IOException e) {
      throw new Sl4aException("Cannot open URL: " + mUrl, e);
    }

    int contentLength = connection.getContentLength();

    if (mFile.exists() && contentLength == mFile.length()) {
      Log.v("Output file already exists. Skipping download.");
      return 0l;
    }

    try {
      mProgressReportingOutputStream = new ProgressReportingOutputStream(mFile);
    } catch (FileNotFoundException e) {
      throw new Sl4aException(e);
    }

    publishProgress(0, contentLength);

    int bytesCopied = IoUtils.copy(connection.getInputStream(), mProgressReportingOutputStream);
    if (bytesCopied != contentLength && contentLength != -1) {
      throw new IOException("Download incomplete: " + bytesCopied + " != " + contentLength);
    }
    mProgressReportingOutputStream.close();
    Log.v("Download completed successfully.");
    return bytesCopied;
  }
}
