package fr.free.nrw.commons.upload;

import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import java.io.IOException;
import java.util.Date;

import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.HandlerService;
import fr.free.nrw.commons.Prefs;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.contributions.Contribution;

public class UploadController {
    private UploadService uploadService;

    private final Activity activity;
    final CommonsApplication app;

    public interface ContributionUploadProgress {
        void onUploadStarted(Contribution contribution);
    }

    public UploadController(Activity activity) {
        this.activity = activity;
        app = (CommonsApplication)activity.getApplicationContext();
    }

    private boolean isUploadServiceConnected;
    private ServiceConnection uploadServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName componentName, IBinder binder) {
            uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService();
            isUploadServiceConnected = true;
        }

        public void onServiceDisconnected(ComponentName componentName) {
            // this should never happen
            throw new RuntimeException("UploadService died but the rest of the process did not!");
        }
    };

    public void prepareService() {
        Intent uploadServiceIntent = new Intent(activity.getApplicationContext(), UploadService.class);
        uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
        activity.startService(uploadServiceIntent);
        activity.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
    }

    public void cleanup() {
        if(isUploadServiceConnected) {
            activity.unbindService(uploadServiceConnection);
        }
    }

    public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, ContributionUploadProgress onComplete) {
        Contribution contribution;

        String title = rawTitle;
        String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
        // People are used to ".jpg" more than ".jpeg" which the system gives us.
        if (extension != null && extension.toLowerCase().equals("jpeg")) {
            extension = "jpg";
        }
        if(extension != null && !title.toLowerCase().endsWith(extension.toLowerCase())) {
            title += "." + extension;
        }


        contribution = new Contribution(mediaUri, null, title, description, -1, null, null, app.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY);

        contribution.setTag("mimeType", mimeType);
        contribution.setSource(source);

        startUpload(contribution, onComplete);
    }

    public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {


        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);

        if(TextUtils.isEmpty(contribution.getCreator())) {
            contribution.setCreator(app.getCurrentAccount().name);
        }

        if(contribution.getDescription() == null) {
            contribution.setDescription("");
        }

        String license = prefs.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA);
        contribution.setLicense(license);


        //FIXME: Add permission request here. Only executeAsyncTask if permission has been granted
        Utils.executeAsyncTask(new AsyncTask<Void, Void, Contribution>() {

            // Fills up missing information about Contributions
            // Only does things that involve some form of IO
            // Runs in background thread
            @Override
            protected Contribution doInBackground(Void... voids /* stare into you */) {
                long length;
                try {
                    if(contribution.getDataLength() <= 0) {
                        length = activity.getContentResolver().openAssetFileDescriptor(contribution.getLocalUri(), "r").getLength();
                        if(length == -1) {
                            // Let us find out the long way!
                            length = Utils.countBytes(activity.getContentResolver().openInputStream(contribution.getLocalUri()));
                        }
                        contribution.setDataLength(length);
                    }
                } catch(IOException e) {
                    Log.e("UploadController", "IO Exception: ", e);
                } catch(NullPointerException e) {
                    Log.e("UploadController", "Null Pointer Exception: ", e);
                } catch(SecurityException e) {
                    Log.e("UploadController", "Security Exception: ", e);
                }

                String mimeType = (String)contribution.getTag("mimeType");
                if(mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) {
                    mimeType = activity.getContentResolver().getType(contribution.getLocalUri());
                    if(mimeType != null) {
                        contribution.setTag("mimeType", mimeType);
                    }
                }

                if(mimeType.startsWith("image/") && contribution.getDateCreated() == null) {
                    Cursor cursor = activity.getContentResolver().query(contribution.getLocalUri(),
                            new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null);
                    if(cursor != null && cursor.getCount() != 0) {
                        cursor.moveToFirst();
                        Date dateCreated = new Date(cursor.getLong(0));
                        Date epochStart = new Date(0);
                        if(dateCreated.equals(epochStart) || dateCreated.before(epochStart)) {
                            // If date is incorrect (1st second of unix time) then set it to the current date
                            dateCreated = new Date();
                        }
                        contribution.setDateCreated(dateCreated);
                        cursor.close();
                    } else {
                        contribution.setDateCreated(new Date());
                    }
                }

                return contribution;
            }

            @Override
            protected void onPostExecute(Contribution contribution) {
                super.onPostExecute(contribution);
                uploadService.queue(UploadService.ACTION_UPLOAD_FILE, contribution);
                onComplete.onUploadStarted(contribution);
            }
        });
    }
}

@@ -5452,24 +5452,70 @@
 mimeType%22);%0A
+                Boolean imagePrefix = false;%0A%0A
             
@@ -5798,32 +5798,101 @@
 pe%22, mimeType);%0A
+                        imagePrefix = mimeType.startsWith(%22image/%22);%0A
                 
@@ -5939,37 +5939,19 @@
  if(
-mimeType.startsWith(%22image/%22)
+imagePrefix
  && 
@@ -6952,33 +6952,32 @@
               %7D%0A
-%0A
                 

Add null check