package com.zegoggles.smssync.mail;

import android.content.ContentResolver;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.filter.Base64OutputStream;
import com.fsck.k9.mail.internet.MimeBodyPart;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.TextBody;
import org.apache.commons.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import static com.zegoggles.smssync.App.TAG;

class Attachment {
    // RFC2231 encoding from geronimo-javamail
    private static final String MIME_SPECIALS = "()<>@,;:\\\"/[]?=" + "\t ";
    private static final String RFC2231_SPECIALS = "*'%" + MIME_SPECIALS;
    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    private Attachment() {}

    public static MimeBodyPart createTextPart(String text) throws MessagingException {
        return new MimeBodyPart(new TextBody(text));
    }

    public static MimeBodyPart createPartFromUri(ContentResolver resolver, Uri uri, String filename, String contentType) throws MessagingException {
        return createPart(new ResolverBody(resolver, uri), filename, contentType);
    }

    public static MimeBodyPart createPartFromFile(File file, String contentType) throws MessagingException {
        return createPart(new FileBody(file), file.getName(), contentType);
    }

    private static MimeBodyPart createPart(Body body, final String filename, final String contentType) throws MessagingException {
        MimeBodyPart part = new MimeBodyPart(body, contentType);

        String contentTypeHeader = TextUtils.isEmpty(contentType) ? "application/octet-stream" : contentType;
        String disposition = "attachment";
        if (!TextUtils.isEmpty(filename)) {
            // should set both name and filename parameters
            // http://www.imc.org/ietf-smtp/mail-archive/msg05023.html
            disposition += encodeRFC2231("filename", filename);
            contentTypeHeader += encodeRFC2231("name", filename);
        }
        part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentTypeHeader);
        part.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, disposition);
        part.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
        return part;
    }

    private static abstract class Base64Body implements Body {
        @Override
        public void writeTo(OutputStream outputStream) throws IOException, MessagingException {
            InputStream in = getInputStream();
            if (in != null)  {
                Base64OutputStream base64Out = new Base64OutputStream(outputStream);
                IOUtils.copy(in, base64Out);
                base64Out.close();
            } else {
                Log.w(TAG, "input stream is null");
            }
        }
    }

    private static class ResolverBody extends Base64Body {
        private ContentResolver resolver;
        private Uri uri;

        public ResolverBody(ContentResolver contentResolver, Uri uri) {
            resolver = contentResolver;
            this.uri = uri;
        }

        public InputStream getInputStream() throws MessagingException {
            try {
                return resolver.openInputStream(uri);
            } catch (FileNotFoundException fnfe) {
                /*
                 * Since it's completely normal for us to try to serve up attachments that
                 * have been blown away, we just return an empty stream.
                 */
                return new ByteArrayInputStream(new byte[0]);
            }
        }

        @Override
        public void setEncoding(String s) throws MessagingException {
        }
    }

    private static class FileBody extends Base64Body {
        private final File file;

        public FileBody(File file) {
            this.file = file;
        }

        @Override
        public InputStream getInputStream() throws MessagingException {
            try {
                return new FileInputStream(file);
            } catch (FileNotFoundException e) {
                return new ByteArrayInputStream(new byte[0]);
            }
        }

        @Override
        public void setEncoding(String s) throws MessagingException {
        }
    }

    protected static String encodeRFC2231(String key, String value) {
        StringBuilder buf = new StringBuilder();
        boolean encoded = encodeRFC2231value(value, buf);
        if (encoded) {
            return "; " + key + "*=" + buf.toString();
        } else {
            return "; " + key + "=" + value;
        }
    }

    private static boolean encodeRFC2231value(String value, StringBuilder buf) {
        String charset = "UTF-8";
        buf.append(charset);
        buf.append("''"); // no language
        byte[] bytes;
        try {
            bytes = value.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            return true;
        }
        boolean encoded = false;
        for (byte aByte : bytes) {
            int ch = aByte & 0xff;
            if (ch <= 32 || ch >= 127 || RFC2231_SPECIALS.indexOf(ch) != -1) {
                buf.append('%');
                buf.append(HEX_DIGITS[ch >> 4]);
                buf.append(HEX_DIGITS[ch & 0xf]);
                encoded = true;
            } else {
                buf.append((char) ch);
            }
        }
        return encoded;
    }
}

@@ -371,51 +371,8 @@
 er;%0A
-import com.fsck.k9.mail.internet.TextBody;%0A
 impo
@@ -447,61 +447,8 @@
 am;%0A
-import java.io.File;%0Aimport java.io.FileInputStream;%0A
 impo
@@ -992,162 +992,8 @@
     
-public static MimeBodyPart createTextPart(String text) throws MessagingException %7B%0A        return new MimeBodyPart(new TextBody(text));%0A    %7D%0A%0A    public 
 stat
@@ -1220,200 +1220,8 @@
  %7D%0A%0A
-    public static MimeBodyPart createPartFromFile(File file, String contentType) throws MessagingException %7B%0A        return createPart(new FileBody(file), file.getName(), contentType);%0A    %7D%0A%0A
     
@@ -2798,23 +2798,16 @@
         
-public 
 Resolver
@@ -2981,34 +2981,8 @@
 am()
- throws MessagingException
  %7B%0A 
@@ -3456,599 +3456,8 @@
 g s)
- throws MessagingException %7B%0A        %7D%0A    %7D%0A%0A    private static class FileBody extends Base64Body %7B%0A        private final File file;%0A%0A        public FileBody(File file) %7B%0A            this.file = file;%0A        %7D%0A%0A        @Override%0A        public InputStream getInputStream() throws MessagingException %7B%0A            try %7B%0A                return new FileInputStream(file);%0A            %7D catch (FileNotFoundException e) %7B%0A                return new ByteArrayInputStream(new byte%5B0%5D);%0A            %7D%0A        %7D%0A%0A        @Override%0A        public void setEncoding(String s) throws MessagingException
  %7B%0A 
@@ -3480,18 +3480,8 @@
     
-protected 
 stat

Remove dead code