/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.exchange.adapter;

import android.content.ContentProviderOperation;
import android.content.Context;
import android.content.OperationApplicationException;
import android.os.RemoteException;
import android.util.Log;

import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.service.SearchParams;
import com.android.emailcommon.utility.TextUtilities;
import com.android.exchange.Eas;
import com.android.exchange.EasResponse;
import com.android.exchange.EasSyncService;
import com.android.exchange.ExchangeService;
import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;

import org.apache.http.HttpStatus;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * Implementation of server-side search for EAS using the EmailService API
 */
public class Search {
    // The shortest search query we'll accept
    // TODO Check with UX whether this is correct
    private static final int MIN_QUERY_LENGTH = 3;
    // The largest number of results we'll ask for per server request
    private static final int MAX_SEARCH_RESULTS = 100;

    public static int searchMessages(Context context, long accountId, SearchParams searchParams,
            long destMailboxId) {
        // Sanity check for arguments
        int offset = searchParams.mOffset;
        int limit = searchParams.mLimit;
        String filter = searchParams.mFilter;
        if (limit < 0 || limit > MAX_SEARCH_RESULTS || offset < 0) return 0;
        // TODO Should this be checked in UI?  Are there guidelines for minimums?
        if (filter == null || filter.length() < MIN_QUERY_LENGTH) return 0;

        int res = 0;
        Account account = Account.restoreAccountWithId(context, accountId);
        if (account == null) return res;
        EasSyncService svc = EasSyncService.setupServiceForAccount(context, account);
        if (svc == null) return res;
        try {
            Mailbox searchMailbox = Mailbox.restoreMailboxWithId(context, destMailboxId);
            // Sanity check; account might have been deleted?
            if (searchMailbox == null) return res;
            svc.mMailbox = searchMailbox;
            svc.mAccount = account;
            Serializer s = new Serializer();
            s.start(Tags.SEARCH_SEARCH).start(Tags.SEARCH_STORE);
            s.data(Tags.SEARCH_NAME, "Mailbox");
            s.start(Tags.SEARCH_QUERY).start(Tags.SEARCH_AND);
            s.data(Tags.SYNC_CLASS, "Email");

            // If this isn't an inbox search, then include the collection id
            Mailbox inbox = Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_INBOX);
            if (inbox == null) return 0;
            if (searchParams.mMailboxId != inbox.mId) {
                s.data(Tags.SYNC_COLLECTION_ID, inbox.mServerId);
            }

            s.data(Tags.SEARCH_FREE_TEXT, filter);
            s.end().end();              // SEARCH_AND, SEARCH_QUERY
            s.start(Tags.SEARCH_OPTIONS);
            if (offset == 0) {
                s.tag(Tags.SEARCH_REBUILD_RESULTS);
            }
            if (searchParams.mIncludeChildren) {
                s.tag(Tags.SEARCH_DEEP_TRAVERSAL);
            }
            // Range is sent in the form first-last (e.g. 0-9)
            s.data(Tags.SEARCH_RANGE, offset + "-" + (offset + limit - 1));
            s.start(Tags.BASE_BODY_PREFERENCE);
            s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_HTML);
            s.data(Tags.BASE_TRUNCATION_SIZE, "20000");
            s.end();                    // BASE_BODY_PREFERENCE
            s.end().end().end().done(); // SEARCH_OPTIONS, SEARCH_STORE, SEARCH_SEARCH
            EasResponse resp = svc.sendHttpClientPost("Search", s.toByteArray());
            try {
                int code = resp.getStatus();
                if (code == HttpStatus.SC_OK) {
                    InputStream is = resp.getInputStream();
                    try {
                        SearchParser sp = new SearchParser(is, svc, filter);
                        sp.parse();
                        res = sp.getTotalResults();
                    } finally {
                        is.close();
                    }
                } else {
                    svc.userLog("Search returned " + code);
                }
            } finally {
                resp.close();
            }
        } catch (IOException e) {
            svc.userLog("Search exception " + e);
        } finally {
            try {
                ExchangeService.callback().syncMailboxStatus(destMailboxId,
                        EmailServiceStatus.SUCCESS, 100);
            } catch (RemoteException e) {
            }
        }
        // Return the total count
        return res;
    }

    /**
     * Parse the result of a Search command
     */
    static class SearchParser extends Parser {
        private final EasSyncService mService;
        private final String mQuery;
        private int mTotalResults;

        private SearchParser(InputStream in, EasSyncService service, String query)
                throws IOException {
            super(in);
            mService = service;
            mQuery = query;
        }

        protected int getTotalResults() {
            return mTotalResults;
        }

        @Override
        public boolean parse() throws IOException {
            boolean res = false;
            if (nextTag(START_DOCUMENT) != Tags.SEARCH_SEARCH) {
                throw new IOException();
            }
            while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
                if (tag == Tags.SEARCH_STATUS) {
                    String status = getValue();
                    if (Eas.USER_LOG) {
                        Log.d(Logging.LOG_TAG, "Search status: " + status);
                    }
                } else if (tag == Tags.SEARCH_RESPONSE) {
                    parseResponse();
                } else {
                    skipTag();
                }
            }
            return res;
        }

        private boolean parseResponse() throws IOException {
            boolean res = false;
            while (nextTag(Tags.SEARCH_RESPONSE) != END) {
                if (tag == Tags.SEARCH_STORE) {
                    parseStore();
                } else {
                    skipTag();
                }
            }
            return res;
        }

        private boolean parseStore() throws IOException {
            EmailSyncAdapter adapter = new EmailSyncAdapter(mService);
            EasEmailSyncParser parser = adapter.new EasEmailSyncParser(this, adapter);
            ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
            boolean res = false;

            while (nextTag(Tags.SEARCH_STORE) != END) {
                if (tag == Tags.SEARCH_STATUS) {
                    String status = getValue();
                } else if (tag == Tags.SEARCH_TOTAL) {
                    mTotalResults = getValueInt();
                } else if (tag == Tags.SEARCH_RESULT) {
                    parseResult(parser, ops);
                } else {
                    skipTag();
                }
            }

            try {
                adapter.mContentResolver.applyBatch(EmailContent.AUTHORITY, ops);
                if (Eas.USER_LOG) {
                    mService.userLog("Saved " + ops.size() + " search results");
                }
            } catch (RemoteException e) {
                Log.d(Logging.LOG_TAG, "RemoteException while saving search results.");
            } catch (OperationApplicationException e) {
            }

            return res;
        }

        private boolean parseResult(EasEmailSyncParser parser,
                ArrayList<ContentProviderOperation> ops) throws IOException {
            // Get an email sync parser for our incoming message data
            boolean res = false;
            Message msg = new Message();
            while (nextTag(Tags.SEARCH_RESULT) != END) {
                if (tag == Tags.SYNC_CLASS) {
                    getValue();
                } else if (tag == Tags.SYNC_COLLECTION_ID) {
                    getValue();
                } else if (tag == Tags.SEARCH_LONG_ID) {
                    msg.mProtocolSearchInfo = getValue();
                } else if (tag == Tags.SEARCH_PROPERTIES) {
                    msg.mAccountKey = mService.mAccount.mId;
                    msg.mMailboxKey = mService.mMailbox.mId;
                    msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;
                    parser.pushTag(tag);
                    parser.addData(msg, tag);
                    if (msg.mHtml != null) {
                        msg.mHtml = TextUtilities.highlightTermsInHtml(msg.mHtml, mQuery);
                    }
                    msg.addSaveOps(ops);
                } else {
                    skipTag();
                }
            }
            return res;
        }
    }
}
