/**
 * Copyright (c) 2011, 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.android.mail.providers;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.emailcommon.internet.MimeUtility;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Part;
import com.android.mail.browse.MessageAttachmentBar;
import com.android.mail.providers.UIProvider.AttachmentColumns;
import com.android.mail.providers.UIProvider.AttachmentDestination;
import com.android.mail.providers.UIProvider.AttachmentRendition;
import com.android.mail.providers.UIProvider.AttachmentState;
import com.android.mail.providers.UIProvider.AttachmentType;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.MimeType;
import com.android.mail.utils.Utils;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;

import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;

public class Attachment implements Parcelable {
    public static final int MAX_ATTACHMENT_PREVIEWS = 2;
    public static final String LOG_TAG = LogTag.getLogTag();
    /**
     * Workaround for b/8070022 so that appending a null partId to the end of a
     * uri wouldn't remove the trailing backslash
     */
    public static final String EMPTY_PART_ID = "empty";

    // Indicates that this is a dummy placeholder attachment.
    public static final int FLAG_DUMMY_ATTACHMENT = 1<<10;

    /**
     * Part id of the attachment.
     */
    public String partId;

    /**
     * Attachment file name. See {@link AttachmentColumns#NAME} Use {@link #setName(String)}.
     */
    private String name;

    /**
     * Attachment size in bytes. See {@link AttachmentColumns#SIZE}.
     */
    public int size;

    /**
     * The provider-generated URI for this Attachment. Must be globally unique.
     * For local attachments generated by the Compose UI prior to send/save,
     * this field will be null.
     *
     * @see AttachmentColumns#URI
     */
    public Uri uri;

    /**
     * MIME type of the file. Use {@link #getContentType()} and {@link #setContentType(String)}.
     *
     * @see AttachmentColumns#CONTENT_TYPE
     */
    private String contentType;
    private String inferredContentType;

    /**
     * Use {@link #setState(int)}
     *
     * @see AttachmentColumns#STATE
     */
    public int state;

    /**
     * @see AttachmentColumns#DESTINATION
     */
    public int destination;

    /**
     * @see AttachmentColumns#DOWNLOADED_SIZE
     */
    public int downloadedSize;

    /**
     * Shareable, openable uri for this attachment
     * <p>
     * content:// Gmail.getAttachmentDefaultUri() if origin is SERVER_ATTACHMENT
     * <p>
     * content:// uri pointing to the content to be uploaded if origin is
     * LOCAL_FILE
     * <p>
     * file:// uri pointing to an EXTERNAL apk file. The package manager only
     * handles file:// uris not content:// uris. We do the same workaround in
     * {@link MessageAttachmentBar#onClick(android.view.View)} and
     * UiProvider#getUiAttachmentsCursorForUIAttachments().
     *
     * @see AttachmentColumns#CONTENT_URI
     */
    public Uri contentUri;

    /**
     * Might be null.
     *
     * @see AttachmentColumns#THUMBNAIL_URI
     */
    public Uri thumbnailUri;

    /**
     * Might be null.
     *
     * @see AttachmentColumns#PREVIEW_INTENT_URI
     */
    public Uri previewIntentUri;

    /**
     * The visibility type of this attachment.
     *
     * @see AttachmentColumns#TYPE
     */
    public int type;

    public int flags;

    /**
     * Might be null. JSON string.
     *
     * @see AttachmentColumns#PROVIDER_DATA
     */
    public String providerData;

    private transient Uri mIdentifierUri;

    /**
     * True if this attachment can be downloaded again.
     */
    private boolean supportsDownloadAgain;


    public Attachment() {
    }

    public Attachment(Parcel in) {
        name = in.readString();
        size = in.readInt();
        uri = in.readParcelable(null);
        contentType = in.readString();
        state = in.readInt();
        destination = in.readInt();
        downloadedSize = in.readInt();
        contentUri = in.readParcelable(null);
        thumbnailUri = in.readParcelable(null);
        previewIntentUri = in.readParcelable(null);
        providerData = in.readString();
        supportsDownloadAgain = in.readInt() == 1;
        type = in.readInt();
        flags = in.readInt();
    }

    public Attachment(Cursor cursor) {
        if (cursor == null) {
            return;
        }

        name = cursor.getString(cursor.getColumnIndex(AttachmentColumns.NAME));
        size = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.SIZE));
        uri = Uri.parse(cursor.getString(cursor.getColumnIndex(AttachmentColumns.URI)));
        contentType = cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_TYPE));
        state = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.STATE));
        destination = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DESTINATION));
        downloadedSize = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DOWNLOADED_SIZE));
        contentUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_URI)));
        thumbnailUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.THUMBNAIL_URI)));
        previewIntentUri = parseOptionalUri(
                cursor.getString(cursor.getColumnIndex(AttachmentColumns.PREVIEW_INTENT_URI)));
        providerData = cursor.getString(cursor.getColumnIndex(AttachmentColumns.PROVIDER_DATA));
        supportsDownloadAgain = cursor.getInt(
                cursor.getColumnIndex(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN)) == 1;
        type = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.TYPE));
        flags = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.FLAGS));
    }

    public Attachment(JSONObject srcJson) {
        name = srcJson.optString(AttachmentColumns.NAME, null);
        size = srcJson.optInt(AttachmentColumns.SIZE);
        uri = parseOptionalUri(srcJson, AttachmentColumns.URI);
        contentType = srcJson.optString(AttachmentColumns.CONTENT_TYPE, null);
        state = srcJson.optInt(AttachmentColumns.STATE);
        destination = srcJson.optInt(AttachmentColumns.DESTINATION);
        downloadedSize = srcJson.optInt(AttachmentColumns.DOWNLOADED_SIZE);
        contentUri = parseOptionalUri(srcJson, AttachmentColumns.CONTENT_URI);
        thumbnailUri = parseOptionalUri(srcJson, AttachmentColumns.THUMBNAIL_URI);
        previewIntentUri = parseOptionalUri(srcJson, AttachmentColumns.PREVIEW_INTENT_URI);
        providerData = srcJson.optString(AttachmentColumns.PROVIDER_DATA);
        supportsDownloadAgain = srcJson.optBoolean(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, true);
        type = srcJson.optInt(AttachmentColumns.TYPE);
        flags = srcJson.optInt(AttachmentColumns.FLAGS);
    }

    /**
     * Constructor for use when creating attachments in eml files.
     */
    public Attachment(Context context, Part part, Uri emlFileUri, String messageId, String partId) {
        try {
            // Transfer fields from mime format to provider format
            final String contentTypeHeader = MimeUtility.unfoldAndDecode(part.getContentType());
            name = MimeUtility.getHeaderParameter(contentTypeHeader, "name");
            if (name == null) {
                final String contentDisposition =
                        MimeUtility.unfoldAndDecode(part.getDisposition());
                name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
            }

            contentType = MimeType.inferMimeType(name, part.getMimeType());
            uri = EmlAttachmentProvider.getAttachmentUri(emlFileUri, messageId, partId);
            contentUri = uri;
            thumbnailUri = uri;
            previewIntentUri = null;
            state = AttachmentState.SAVED;
            providerData = null;
            supportsDownloadAgain = false;
            destination = AttachmentDestination.CACHE;
            type = AttachmentType.STANDARD;
            flags = 0;

            // insert attachment into content provider so that we can open the file
            final ContentResolver resolver = context.getContentResolver();
            resolver.insert(uri, toContentValues());

            // save the file in the cache
            try {
                final InputStream in = part.getBody().getInputStream();
                final OutputStream out = resolver.openOutputStream(uri, "rwt");
                size = IOUtils.copy(in, out);
                downloadedSize = size;
                in.close();
                out.close();
            } catch (FileNotFoundException e) {
                LogUtils.e(LOG_TAG, e, "Error in writing attachment to cache");
            } catch (IOException e) {
                LogUtils.e(LOG_TAG, e, "Error in writing attachment to cache");
            }
            // perform a second insert to put the updated size and downloaded size values in
            resolver.insert(uri, toContentValues());
        } catch (MessagingException e) {
            LogUtils.e(LOG_TAG, e, "Error parsing eml attachment");
        }
    }

    /**
     * Create an attachment from a {@link ContentValues} object.
     * The keys should be {@link AttachmentColumns}.
     */
    public Attachment(ContentValues values) {
        name = values.getAsString(AttachmentColumns.NAME);
        size = values.getAsInteger(AttachmentColumns.SIZE);
        uri = parseOptionalUri(values.getAsString(AttachmentColumns.URI));
        contentType = values.getAsString(AttachmentColumns.CONTENT_TYPE);
        state = values.getAsInteger(AttachmentColumns.STATE);
        destination = values.getAsInteger(AttachmentColumns.DESTINATION);
        downloadedSize = values.getAsInteger(AttachmentColumns.DOWNLOADED_SIZE);
        contentUri = parseOptionalUri(values.getAsString(AttachmentColumns.CONTENT_URI));
        thumbnailUri = parseOptionalUri(values.getAsString(AttachmentColumns.THUMBNAIL_URI));
        previewIntentUri =
                parseOptionalUri(values.getAsString(AttachmentColumns.PREVIEW_INTENT_URI));
        providerData = values.getAsString(AttachmentColumns.PROVIDER_DATA);
        supportsDownloadAgain = values.getAsBoolean(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN);
        type = values.getAsInteger(AttachmentColumns.TYPE);
        flags = values.getAsInteger(AttachmentColumns.FLAGS);
    }

    /**
     * Returns the various attachment fields in a {@link ContentValues} object.
     * The keys for each field should be {@link AttachmentColumns}.
     */
    public ContentValues toContentValues() {
        final ContentValues values = new ContentValues(12);

        values.put(AttachmentColumns.NAME, name);
        values.put(AttachmentColumns.SIZE, size);
        values.put(AttachmentColumns.URI, uri.toString());
        values.put(AttachmentColumns.CONTENT_TYPE, contentType);
        values.put(AttachmentColumns.STATE, state);
        values.put(AttachmentColumns.DESTINATION, destination);
        values.put(AttachmentColumns.DOWNLOADED_SIZE, downloadedSize);
        values.put(AttachmentColumns.CONTENT_URI, contentUri.toString());
        values.put(AttachmentColumns.THUMBNAIL_URI, thumbnailUri.toString());
        values.put(AttachmentColumns.PREVIEW_INTENT_URI,
                previewIntentUri == null ? null : previewIntentUri.toString());
        values.put(AttachmentColumns.PROVIDER_DATA, providerData);
        values.put(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, supportsDownloadAgain);
        values.put(AttachmentColumns.TYPE, type);
        values.put(AttachmentColumns.FLAGS, flags);

        return values;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(size);
        dest.writeParcelable(uri, flags);
        dest.writeString(contentType);
        dest.writeInt(state);
        dest.writeInt(destination);
        dest.writeInt(downloadedSize);
        dest.writeParcelable(contentUri, flags);
        dest.writeParcelable(thumbnailUri, flags);
        dest.writeParcelable(previewIntentUri, flags);
        dest.writeString(providerData);
        dest.writeInt(supportsDownloadAgain ? 1 : 0);
        dest.writeInt(type);
        dest.writeInt(flags);
    }

    public JSONObject toJSON() throws JSONException {
        final JSONObject result = new JSONObject();

        result.put(AttachmentColumns.NAME, name);
        result.put(AttachmentColumns.SIZE, size);
        result.put(AttachmentColumns.URI, stringify(uri));
        result.put(AttachmentColumns.CONTENT_TYPE, contentType);
        result.put(AttachmentColumns.STATE, state);
        result.put(AttachmentColumns.DESTINATION, destination);
        result.put(AttachmentColumns.DOWNLOADED_SIZE, downloadedSize);
        result.put(AttachmentColumns.CONTENT_URI, stringify(contentUri));
        result.put(AttachmentColumns.THUMBNAIL_URI, stringify(thumbnailUri));
        result.put(AttachmentColumns.PREVIEW_INTENT_URI, stringify(previewIntentUri));
        result.put(AttachmentColumns.PROVIDER_DATA, providerData);
        result.put(AttachmentColumns.SUPPORTS_DOWNLOAD_AGAIN, supportsDownloadAgain);
        result.put(AttachmentColumns.TYPE, type);
        result.put(AttachmentColumns.FLAGS, flags);

        return result;
    }

    @Override
    public String toString() {
        try {
            final JSONObject jsonObject = toJSON();
            // Add some additional fields that are helpful when debugging issues
            jsonObject.put("partId", partId);
            if (providerData != null) {
                try {
                    // pretty print the provider data
                    jsonObject.put(AttachmentColumns.PROVIDER_DATA, new JSONObject(providerData));
                } catch (JSONException e) {
                    LogUtils.e(LOG_TAG, e, "JSONException when adding provider data");
                }
            }
            return jsonObject.toString(4);
        } catch (JSONException e) {
            LogUtils.e(LOG_TAG, e, "JSONException in toString");
            return super.toString();
        }
    }

    private static String stringify(Object object) {
        return object != null ? object.toString() : null;
    }

    protected static Uri parseOptionalUri(String uriString) {
        return uriString == null ? null : Uri.parse(uriString);
    }

    protected static Uri parseOptionalUri(JSONObject srcJson, String key) {
        final String uriStr = srcJson.optString(key, null);
        return uriStr == null ? null : Uri.parse(uriStr);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public boolean isPresentLocally() {
        return state == AttachmentState.SAVED;
    }

    public boolean canSave() {
        return !isSavedToExternal() && !isInstallable();
    }

    public boolean canShare() {
        return isPresentLocally() && contentUri != null;
    }

    public boolean isDownloading() {
        return state == AttachmentState.DOWNLOADING || state == AttachmentState.PAUSED;
    }

    public boolean isSavedToExternal() {
        return state == AttachmentState.SAVED && destination == AttachmentDestination.EXTERNAL;
    }

    public boolean isInstallable() {
        return MimeType.isInstallable(getContentType());
    }

    public boolean shouldShowProgress() {
        return (state == AttachmentState.DOWNLOADING || state == AttachmentState.PAUSED)
                && size > 0 && downloadedSize > 0 && downloadedSize <= size;
    }

    public boolean isDownloadFailed() {
        return state == AttachmentState.FAILED;
    }

    public boolean isDownloadFinishedOrFailed() {
        return state == AttachmentState.FAILED || state == AttachmentState.SAVED;
    }

    public boolean supportsDownloadAgain() {
        return supportsDownloadAgain;
    }

    public boolean canPreview() {
        return previewIntentUri != null;
    }

    /**
     * Returns a stable identifier URI for this attachment. TODO: make the uri
     * field stable, and put provider-specific opaque bits and bobs elsewhere
     */
    public Uri getIdentifierUri() {
        if (Utils.isEmpty(mIdentifierUri)) {
            mIdentifierUri = Utils.isEmpty(uri) ?
                    (Utils.isEmpty(contentUri) ? Uri.EMPTY : contentUri)
                    : uri.buildUpon().clearQuery().build();
        }
        return mIdentifierUri;
    }

    public String getContentType() {
        if (TextUtils.isEmpty(inferredContentType)) {
            inferredContentType = MimeType.inferMimeType(name, contentType);
        }
        return inferredContentType;
    }

    public Uri getUriForRendition(int rendition) {
        final Uri uri;
        switch (rendition) {
            case AttachmentRendition.BEST:
                uri = contentUri;
                break;
            case AttachmentRendition.SIMPLE:
                uri = thumbnailUri;
                break;
            default:
                throw new IllegalArgumentException("invalid rendition: " + rendition);
        }
        return uri;
    }

    public void setContentType(String contentType) {
        if (!TextUtils.equals(this.contentType, contentType)) {
            this.inferredContentType = null;
            this.contentType = contentType;
        }
    }

    public String getName() {
        return name;
    }

    public boolean setName(String name) {
        if (!TextUtils.equals(this.name, name)) {
            this.inferredContentType = null;
            this.name = name;
            return true;
        }
        return false;
    }

    /**
     * Sets the attachment state. Side effect: sets downloadedSize
     */
    public void setState(int state) {
        this.state = state;
        if (state == AttachmentState.FAILED || state == AttachmentState.NOT_SAVED) {
            this.downloadedSize = 0;
        }
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final Attachment that = (Attachment) o;

        if (destination != that.destination) {
            return false;
        }
        if (downloadedSize != that.downloadedSize) {
            return false;
        }
        if (size != that.size) {
            return false;
        }
        if (state != that.state) {
            return false;
        }
        if (supportsDownloadAgain != that.supportsDownloadAgain) {
            return false;
        }
        if (type != that.type) {
            return false;
        }
        if (contentType != null ? !contentType.equals(that.contentType)
                : that.contentType != null) {
            return false;
        }
        if (contentUri != null ? !contentUri.equals(that.contentUri) : that.contentUri != null) {
            return false;
        }
        if (name != null ? !name.equals(that.name) : that.name != null) {
            return false;
        }
        if (partId != null ? !partId.equals(that.partId) : that.partId != null) {
            return false;
        }
        if (previewIntentUri != null ? !previewIntentUri.equals(that.previewIntentUri)
                : that.previewIntentUri != null) {
            return false;
        }
        if (providerData != null ? !providerData.equals(that.providerData)
                : that.providerData != null) {
            return false;
        }
        if (thumbnailUri != null ? !thumbnailUri.equals(that.thumbnailUri)
                : that.thumbnailUri != null) {
            return false;
        }
        if (uri != null ? !uri.equals(that.uri) : that.uri != null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result = partId != null ? partId.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + size;
        result = 31 * result + (uri != null ? uri.hashCode() : 0);
        result = 31 * result + (contentType != null ? contentType.hashCode() : 0);
        result = 31 * result + state;
        result = 31 * result + destination;
        result = 31 * result + downloadedSize;
        result = 31 * result + (contentUri != null ? contentUri.hashCode() : 0);
        result = 31 * result + (thumbnailUri != null ? thumbnailUri.hashCode() : 0);
        result = 31 * result + (previewIntentUri != null ? previewIntentUri.hashCode() : 0);
        result = 31 * result + type;
        result = 31 * result + (providerData != null ? providerData.hashCode() : 0);
        result = 31 * result + (supportsDownloadAgain ? 1 : 0);
        return result;
    }

    public static String toJSONArray(Collection<? extends Attachment> attachments) {
        if (attachments == null) {
            return null;
        }
        final JSONArray result = new JSONArray();
        try {
            for (Attachment attachment : attachments) {
                result.put(attachment.toJSON());
            }
        } catch (JSONException e) {
            throw new IllegalArgumentException(e);
        }
        return result.toString();
    }

    public static List<Attachment> fromJSONArray(String jsonArrayStr) {
        final List<Attachment> results = Lists.newArrayList();
        if (jsonArrayStr != null) {
            try {
                final JSONArray arr = new JSONArray(jsonArrayStr);

                for (int i = 0; i < arr.length(); i++) {
                    results.add(new Attachment(arr.getJSONObject(i)));
                }

            } catch (JSONException e) {
                throw new IllegalArgumentException(e);
            }
        }
        return results;
    }

    private static final String SERVER_ATTACHMENT = "SERVER_ATTACHMENT";
    private static final String LOCAL_FILE = "LOCAL_FILE";

    public String toJoinedString() {
        return TextUtils.join(UIProvider.ATTACHMENT_INFO_DELIMITER, Lists.newArrayList(
                partId == null ? "" : partId,
                name == null ? ""
                        : name.replaceAll("[" + UIProvider.ATTACHMENT_INFO_DELIMITER
                                + UIProvider.ATTACHMENT_INFO_SEPARATOR + "]", ""),
                getContentType(),
                String.valueOf(size),
                getContentType(),
                contentUri != null ? SERVER_ATTACHMENT : LOCAL_FILE,
                contentUri != null ? contentUri.toString() : "",
                "" /* cachedFileUri */,
                String.valueOf(type)));
    }

    /**
     * For use with {@link UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES}.
     *
     * @param previewStates The packed int describing the states of multiple attachments.
     * @param attachmentIndex The index of the attachment to update.
     * @param rendition The rendition of that attachment to update.
     * @param downloaded Whether that specific rendition is downloaded.
     * @return A packed int describing the updated downloaded states of the multiple attachments.
     */
    public static int updatePreviewStates(int previewStates, int attachmentIndex, int rendition,
            boolean downloaded) {
        // find the bit that describes that specific attachment index and rendition
        int shift = attachmentIndex * 2 + rendition;
        int mask = 1 << shift;
        // update the packed int at that bit
        if (downloaded) {
            // turns that bit into a 1
            return previewStates | mask;
        } else {
            // turns that bit into a 0
            return previewStates & ~mask;
        }
    }

    /**
     * For use with {@link UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES}.
     *
     * @param previewStates The packed int describing the states of multiple attachments.
     * @param attachmentIndex The index of the attachment.
     * @param rendition The rendition of the attachment.
     * @return The downloaded state of that particular rendition of that particular attachment.
     */
    public static boolean getPreviewState(int previewStates, int attachmentIndex, int rendition) {
        // find the bit that describes that specific attachment index
        int shift = attachmentIndex * 2;
        int mask = 1 << shift;

        if (rendition == AttachmentRendition.SIMPLE) {
            // implicit shift of 0 finds the SIMPLE rendition bit
            return (previewStates & mask) != 0;
        } else if (rendition == AttachmentRendition.BEST) {
            // shift of 1 finds the BEST rendition bit
            return (previewStates & (mask << 1)) != 0;
        } else {
            return false;
        }
    }

    public static final Creator<Attachment> CREATOR = new Creator<Attachment>() {
            @Override
        public Attachment createFromParcel(Parcel source) {
            return new Attachment(source);
        }

            @Override
        public Attachment[] newArray(int size) {
            return new Attachment[size];
        }
    };
}
