package co.smartreceipts.android.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Locale;

import co.smartreceipts.android.utils.log.Logger;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.webkit.MimeTypeMap;

public class Attachment {

	private static final String PDF_EXTENSION = "pdf";
	private static final String SMR_EXTENSION = "smr";
	private static final String PNG_EXTENSION = "png";
	private static final String JPG_EXTENSION = "jpg";
	private static final String JPEG_EXTENSION = "jpeg";
	
	private final Uri mUri;
	private final String mAction;
	private final String mExtension;
	private boolean mIsValid;
	
	public Attachment(Intent intent, ContentResolver resolver) {
		if (intent != null && intent.getAction() != null) {
			mAction = intent.getAction();
			if (Intent.ACTION_VIEW.equals(mAction) && intent.getData() != null) {
				mUri = intent.getData();
				mExtension = getExtension(resolver, mUri);
				mIsValid = true;
			}
			else if (Intent.ACTION_SEND.equals(mAction) && intent.getExtras() != null) {
				final Uri extraStreamUri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM);
				final Uri resolvedUri = resolveUri(extraStreamUri, resolver, MediaStore.Images.ImageColumns.DATA);
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
					// For M, just use the "content://" one instead of the "file://"
					mUri = extraStreamUri;
				} else {
					mUri = resolvedUri;
				}
				mExtension = (resolvedUri != null) ? resolvedUri.toString().substring(resolvedUri.toString().lastIndexOf(".") + 1) : "";
				mIsValid = true;
			}
			else {
				mUri = null; mExtension = null;
				mIsValid = false;
			}
		}
		else {
			mUri = null; mAction = null; mExtension = null;
			mIsValid = false;
		}
		if (mUri == null) {
			mIsValid = false;
		}
		Logger.debug(this, "Action: " + mAction);
		Logger.debug(this, "Extension: " + mExtension);
		Logger.debug(this, "Uri: " + mUri);
	}
	
	private String getExtension(ContentResolver resolver, Uri uri) {
		String extension = mUri.toString().substring(mUri.toString().lastIndexOf(".") + 1);
		extension = (!TextUtils.isEmpty(extension) && extension.length() < 5) ? extension : MimeTypeMap.getSingleton().getExtensionFromMimeType(resolver.getType(uri));
		if (!TextUtils.isEmpty(extension)) {
			return extension.toLowerCase(Locale.US);
		}
		else {
			return SMR_EXTENSION; //q&d hack
		}
	}
	
	private Uri resolveUri(Uri uri, ContentResolver resolver, String column) {
		Cursor cursor = null;
		try {
	        cursor = resolver.query(uri, null, null, null, null); 
	        if (cursor == null) { // local file path (i.e. Dropbox)
	        	return Uri.parse(uri.toString());
	        } 
	        else { 
	            if (cursor.moveToFirst()) {
                    int idx = cursor.getColumnIndex(column);
                    if (idx >= 0 && cursor.getColumnCount() > 0) {
                        final String path = cursor.getString(idx);
                        if (path != null) {
                            return Uri.fromFile(new File(cursor.getString(idx)));
                        } else {
                            return null;
                        }
                    } else {
                        return null;
                    }
                } else {
                    return null;
                }
	        }
		}
		finally {
			if (cursor != null) cursor.close();
		}
	}
	
	public boolean isValid() {
		return mIsValid;
	}
	
	public Uri getUri() {
		return mUri;
	}
	
	public InputStream openUri(ContentResolver resolver) throws FileNotFoundException {
		return resolver.openInputStream(mUri);
	}
	
	public String getAction() {
		return mAction;
	}
	
	public boolean isActionView() {
		return Intent.ACTION_VIEW.equals(mAction);
	}
	
	public boolean isActionSend() {
		return Intent.ACTION_SEND.equals(mAction);
	}
	
	public String getExtension() {
		return mExtension;
	}
	
	public boolean isPDF() {
		return PDF_EXTENSION.equals(mExtension);
	}
	
	public boolean isImage() {
		return JPG_EXTENSION.equals(mExtension) || JPEG_EXTENSION.equals(mExtension) || PNG_EXTENSION.equals(mExtension);
	}
	
	public boolean isSMR() {
		return SMR_EXTENSION.equals(mExtension);
	}

    /**
     * @return {@code true} if we require storage permissions before continuing (ie we're on Android M+ and our Uri doesn't start with content://)
     */
    public boolean requiresStoragePermissions() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ((mUri != null && !mUri.toString().startsWith(ContentResolver.SCHEME_CONTENT)) || isActionView());
    }
	
	/**
	 * Checks if this is a file that can be attached to a receipt (i.e. PDF or Image)
	 * @return true if so. false otherwise
	 */
	public boolean isDirectlyAttachable() {
		return isActionSend() && (isImage() || isPDF());
	}

}
@@ -1339,24 +1339,100 @@
  != null) %7B%0A
+                Logger.debug(this, %22Managing send action for %7B%7D.%22, intent);%0A
 %09%09%09%09final Ur
@@ -1604,16 +1604,137 @@
 .DATA);%0A
+                Logger.debug(this, %22Found the following Uris: extra =%3E %7B%7D, stream =%3E %7B%7D.%22, extraStreamUri, resolvedUri);%0A
 %09%09%09%09if (
@@ -1779,16 +1779,39 @@
 _CODES.M
+ %7C%7C resolvedUri == null
 ) %7B%0A%09%09%09%09

Handled a case in which the attachment could be null