package com.android.exchange.service;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.util.Xml;

import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.service.EmailServiceProxy;
import com.android.exchange.Eas;
import com.android.exchange.EasResponse;
import com.android.mail.utils.LogUtils;

import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;

/**
 * Performs Autodiscover for Exchange servers. This feature tries to find all the configuration
 * options needed based on just a username and password.
 */
public class EasAutoDiscover extends EasServerConnection {
    private static final String TAG = Eas.LOG_TAG;

    private static final String AUTO_DISCOVER_SCHEMA_PREFIX =
        "http://schemas.microsoft.com/exchange/autodiscover/mobilesync/";
    private static final String AUTO_DISCOVER_PAGE = "/autodiscover/autodiscover.xml";

    // Set of string constants for parsing the autodiscover response.
    // TODO: Merge this into Tags.java? It's not quite the same but conceptually belongs there.
    private static final String ELEMENT_NAME_SERVER = "Server";
    private static final String ELEMENT_NAME_TYPE = "Type";
    private static final String ELEMENT_NAME_MOBILE_SYNC = "MobileSync";
    private static final String ELEMENT_NAME_URL = "Url";
    private static final String ELEMENT_NAME_SETTINGS = "Settings";
    private static final String ELEMENT_NAME_ACTION = "Action";
    private static final String ELEMENT_NAME_ERROR = "Error";
    private static final String ELEMENT_NAME_REDIRECT = "Redirect";
    private static final String ELEMENT_NAME_USER = "User";
    private static final String ELEMENT_NAME_EMAIL_ADDRESS = "EMailAddress";
    private static final String ELEMENT_NAME_DISPLAY_NAME = "DisplayName";
    private static final String ELEMENT_NAME_RESPONSE = "Response";
    private static final String ELEMENT_NAME_AUTODISCOVER = "Autodiscover";

    public EasAutoDiscover(final Context context, final String username, final String password) {
        super(context, new Account(), new HostAuth());
        mHostAuth.mLogin = username;
        mHostAuth.mPassword = password;
        mHostAuth.mFlags = HostAuth.FLAG_AUTHENTICATE | HostAuth.FLAG_SSL;
        mHostAuth.mPort = 443;
    }

    /**
     * Do all the work of autodiscovery.
     * @return A {@link Bundle} with the host information if autodiscovery succeeded. If we failed
     *     due to an authentication failure, we return a {@link Bundle} with no host info but with
     *     an appropriate error code. Otherwise, we return null.
     */
    public Bundle doAutodiscover() {
        final String domain = getDomain();
        if (domain == null) {
            return null;
        }

        final StringEntity entity = buildRequestEntity();
        if (entity == null) {
            return null;
        }
        try {
            final HttpPost post = makePost("https://" + domain + AUTO_DISCOVER_PAGE, entity,
                    "text/xml", false);
            final EasResponse resp = getResponse(post, domain);
            if (resp == null) {
                return null;
            }

            try {
                // resp is either an authentication error, or a good response.
                final int code = resp.getStatus();
                if (code == HttpStatus.SC_UNAUTHORIZED) {
                    final Bundle bundle = new Bundle(1);
                    bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
                            MessagingException.AUTODISCOVER_AUTHENTICATION_FAILED);
                    return bundle;
                } else {
                    final HostAuth hostAuth = parseAutodiscover(resp);
                    if (hostAuth != null) {
                        // Fill in the rest of the HostAuth
                        // We use the user name and password that were successful during
                        // the autodiscover process
                        hostAuth.mLogin = mHostAuth.mLogin;
                        hostAuth.mPassword = mHostAuth.mPassword;
                        // Note: there is no way we can auto-discover the proper client
                        // SSL certificate to use, if one is needed.
                        hostAuth.mPort = 443;
                        hostAuth.mProtocol = Eas.PROTOCOL;
                        hostAuth.mFlags = HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE;
                        final Bundle bundle = new Bundle(2);
                        bundle.putParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH,
                                hostAuth);
                        bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE,
                                MessagingException.NO_ERROR);
                        return bundle;
                    }
                }
            } finally {
                resp.close();
            }
        } catch (final IllegalArgumentException e) {
            // This happens when the domain is malformatted.
            // TODO: Fix sanitizing of the domain -- we try to in UI but apparently not correctly.
            LogUtils.e(TAG, "ISE with domain: %s", domain);
        }
        return null;
    }

    /**
     * Get the domain of our account.
     * @return The domain of the email address.
     */
    private String getDomain() {
        final int amp = mHostAuth.mLogin.indexOf('@');
        if (amp < 0) {
            return null;
        }
        return mHostAuth.mLogin.substring(amp + 1);
    }

    /**
     * Create the payload of the request.
     * @return A {@link StringEntity} for the request XML.
     */
    private StringEntity buildRequestEntity() {
        try {
            final XmlSerializer s = Xml.newSerializer();
            final ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
            s.setOutput(os, "UTF-8");
            s.startDocument("UTF-8", false);
            s.startTag(null, "Autodiscover");
            s.attribute(null, "xmlns", AUTO_DISCOVER_SCHEMA_PREFIX + "requestschema/2006");
            s.startTag(null, "Request");
            s.startTag(null, "EMailAddress").text(mHostAuth.mLogin).endTag(null, "EMailAddress");
            s.startTag(null, "AcceptableResponseSchema");
            s.text(AUTO_DISCOVER_SCHEMA_PREFIX + "responseschema/2006");
            s.endTag(null, "AcceptableResponseSchema");
            s.endTag(null, "Request");
            s.endTag(null, "Autodiscover");
            s.endDocument();
            return new StringEntity(os.toString());
        } catch (final IOException e) {
            // For all exception types, we can simply punt on autodiscover.
        } catch (final IllegalArgumentException e) {
        } catch (final IllegalStateException e) {
        }

        return null;
    }

    /**
     * Perform all requests necessary and get the server response. If the post fails or is
     * redirected, we alter the post and retry.
     * @param post The initial {@link HttpPost} for this request.
     * @param domain The domain for our account.
     * @return If this request succeeded or has an unrecoverable authentication error, an
     *     {@link EasResponse} with the details. For other errors, we return null.
     */
    private EasResponse getResponse(final HttpPost post, final String domain) {
        EasResponse resp = doPost(post, true);
        if (resp == null) {
            LogUtils.d(TAG, "Error in autodiscover, trying aternate address");
            post.setURI(URI.create("https://autodiscover." + domain + AUTO_DISCOVER_PAGE));
            resp = doPost(post, true);
        }
        return resp;
    }

    /**
     * Perform one attempt to get autodiscover information. Redirection and some authentication
     * errors are handled by recursively calls with modified host information.
     * @param post The {@link HttpPost} for this request.
     * @param canRetry Whether we can retry after an authentication failure.
     * @return If this request succeeded or has an unrecoverable authentication error, an
     *     {@link EasResponse} with the details. For other errors, we return null.
     */
    private EasResponse doPost(final HttpPost post, final boolean canRetry) {
        final EasResponse resp;
        try {
            resp = executePost(post);
        } catch (final IOException e) {
            return null;
        }

        final int code = resp.getStatus();

        if (resp.isRedirectError()) {
            final String loc = resp.getRedirectAddress();
            if (loc != null && loc.startsWith("http")) {
                LogUtils.d(TAG, "Posting autodiscover to redirect: " + loc);
                redirectHostAuth(loc);
                post.setURI(URI.create(loc));
                return doPost(post, canRetry);
            }
            return null;
        }

        if (code == HttpStatus.SC_UNAUTHORIZED) {
            if (canRetry && mHostAuth.mLogin.contains("@")) {
                // Try again using the bare user name
                final int atSignIndex = mHostAuth.mLogin.indexOf('@');
                mHostAuth.mLogin = mHostAuth.mLogin.substring(0, atSignIndex);
                LogUtils.d(TAG, "401 received; trying username: %s", mHostAuth.mLogin);
                resetAuthorization(post);
                return doPost(post, false);
            }
        } else if (code != HttpStatus.SC_OK) {
            // We'll try the next address if this doesn't work
            LogUtils.d(TAG, "Bad response code when posting autodiscover: %d", code);
            return null;
        }

        return resp;
    }

    /**
     * Parse the Server element of the server response.
     * @param parser The {@link XmlPullParser}.
     * @param hostAuth The {@link HostAuth} to populate with the results of parsing.
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parseServer(final XmlPullParser parser, final HostAuth hostAuth)
            throws XmlPullParserException, IOException {
        boolean mobileSync = false;
        while (true) {
            final int type = parser.next();
            if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SERVER)) {
                break;
            } else if (type == XmlPullParser.START_TAG) {
                final String name = parser.getName();
                if (name.equals(ELEMENT_NAME_TYPE)) {
                    if (parser.nextText().equals(ELEMENT_NAME_MOBILE_SYNC)) {
                        mobileSync = true;
                    }
                } else if (mobileSync && name.equals(ELEMENT_NAME_URL)) {
                    final String url = parser.nextText();
                    if (url != null) {
                        LogUtils.d(TAG, "Autodiscover URL: %s", url);
                        hostAuth.mAddress = Uri.parse(url).getHost();
                    }
                }
            }
        }
    }

    /**
     * Parse the Settings element of the server response.
     * @param parser The {@link XmlPullParser}.
     * @param hostAuth The {@link HostAuth} to populate with the results of parsing.
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parseSettings(final XmlPullParser parser, final HostAuth hostAuth)
            throws XmlPullParserException, IOException {
        while (true) {
            final int type = parser.next();
            if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SETTINGS)) {
                break;
            } else if (type == XmlPullParser.START_TAG) {
                final String name = parser.getName();
                if (name.equals(ELEMENT_NAME_SERVER)) {
                    parseServer(parser, hostAuth);
                }
            }
        }
    }

    /**
     * Parse the Action element of the server response.
     * @param parser The {@link XmlPullParser}.
     * @param hostAuth The {@link HostAuth} to populate with the results of parsing.
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parseAction(final XmlPullParser parser, final HostAuth hostAuth)
            throws XmlPullParserException, IOException {
        while (true) {
            final int type = parser.next();
            if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_ACTION)) {
                break;
            } else if (type == XmlPullParser.START_TAG) {
                final String name = parser.getName();
                if (name.equals(ELEMENT_NAME_ERROR)) {
                    // Should parse the error
                } else if (name.equals(ELEMENT_NAME_REDIRECT)) {
                    LogUtils.d(TAG, "Redirect: " + parser.nextText());
                } else if (name.equals(ELEMENT_NAME_SETTINGS)) {
                    parseSettings(parser, hostAuth);
                }
            }
        }
    }

    /**
     * Parse the User element of the server response.
     * @param parser The {@link XmlPullParser}.
     * @param hostAuth The {@link HostAuth} to populate with the results of parsing.
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parseUser(final XmlPullParser parser, final HostAuth hostAuth)
            throws XmlPullParserException, IOException {
        while (true) {
            int type = parser.next();
            if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_USER)) {
                break;
            } else if (type == XmlPullParser.START_TAG) {
                String name = parser.getName();
                if (name.equals(ELEMENT_NAME_EMAIL_ADDRESS)) {
                    final String addr = parser.nextText();
                    LogUtils.d(TAG, "Autodiscover, email: %s", addr);
                } else if (name.equals(ELEMENT_NAME_DISPLAY_NAME)) {
                    final String dn = parser.nextText();
                    LogUtils.d(TAG, "Autodiscover, user: %s", dn);
                }
            }
        }
    }

    /**
     * Parse the Response element of the server response.
     * @param parser The {@link XmlPullParser}.
     * @param hostAuth The {@link HostAuth} to populate with the results of parsing.
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parseResponse(final XmlPullParser parser, final HostAuth hostAuth)
            throws XmlPullParserException, IOException {
        while (true) {
            final int type = parser.next();
            if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_RESPONSE)) {
                break;
            } else if (type == XmlPullParser.START_TAG) {
                final String name = parser.getName();
                if (name.equals(ELEMENT_NAME_USER)) {
                    parseUser(parser, hostAuth);
                } else if (name.equals(ELEMENT_NAME_ACTION)) {
                    parseAction(parser, hostAuth);
                }
            }
        }
    }

    /**
     * Parse the server response for the final {@link HostAuth}.
     * @param resp The {@link EasResponse} from the server.
     * @return The final {@link HostAuth} for this server.
     */
    private static HostAuth parseAutodiscover(final EasResponse resp) {
        // The response to Autodiscover is regular XML (not WBXML)
        try {
            final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
            parser.setInput(resp.getInputStream(), "UTF-8");
            if (parser.getEventType() != XmlPullParser.START_DOCUMENT) {
                return null;
            }
            if (parser.next() != XmlPullParser.START_TAG) {
                return null;
            }
            if (!parser.getName().equals(ELEMENT_NAME_AUTODISCOVER)) {
                return null;
            }

            final HostAuth hostAuth = new HostAuth();
            while (true) {
                final int type = parser.nextTag();
                if (type == XmlPullParser.END_TAG && parser.getName()
                        .equals(ELEMENT_NAME_AUTODISCOVER)) {
                    break;
                } else if (type == XmlPullParser.START_TAG && parser.getName()
                        .equals(ELEMENT_NAME_RESPONSE)) {
                    parseResponse(parser, hostAuth);
                    // Valid responses will set the address.
                    if (hostAuth.mAddress != null) {
                        return hostAuth;
                    }
                }
            }
        } catch (final XmlPullParserException e) {
            // Parse error.
        } catch (final IOException e) {
            // Error reading parser.
        }
        return null;
    }
}
