/*
 * 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 android.service.textservice;

import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.text.TextUtils;
import android.text.method.WordIterator;
import android.util.Log;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;

import java.lang.ref.WeakReference;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Locale;

/**
 * SpellCheckerService provides an abstract base class for a spell checker.
 * This class combines a service to the system with the spell checker service interface that
 * spell checker must implement.
 *
 * <p>In addition to the normal Service lifecycle methods, this class
 * introduces a new specific callback that subclasses should override
 * {@link #createSession()} to provide a spell checker session that is corresponding
 * to requested language and so on. The spell checker session returned by this method
 * should extend {@link SpellCheckerService.Session}.
 * </p>
 *
 * <h3>Returning spell check results</h3>
 *
 * <p>{@link SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
 * should return spell check results.
 * It receives {@link android.view.textservice.TextInfo} and returns
 * {@link android.view.textservice.SuggestionsInfo} for the input.
 * You may want to override
 * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} for
 * better performance and quality.
 * </p>
 *
 * <p>Please note that {@link SpellCheckerService.Session#getLocale()} does not return a valid
 * locale before {@link SpellCheckerService.Session#onCreate()} </p>
 *
 */
public abstract class SpellCheckerService extends Service {
    private static final String TAG = SpellCheckerService.class.getSimpleName();
    private static final boolean DBG = false;
    public static final String SERVICE_INTERFACE =
            "android.service.textservice.SpellCheckerService";

    private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);


    /**
     * Implement to return the implementation of the internal spell checker
     * service interface. Subclasses should not override.
     */
    @Override
    public final IBinder onBind(final Intent intent) {
        if (DBG) {
            Log.w(TAG, "onBind");
        }
        return mBinder;
    }

    /**
     * Factory method to create a spell checker session impl
     * @return SpellCheckerSessionImpl which should be overridden by a concrete implementation.
     */
    public abstract Session createSession();

    /**
     * This abstract class should be overridden by a concrete implementation of a spell checker.
     */
    public static abstract class Session {
        private InternalISpellCheckerSession mInternalSession;
        private volatile SentenceLevelAdapter mSentenceLevelAdapter;

        /**
         * @hide
         */
        public final void setInternalISpellCheckerSession(InternalISpellCheckerSession session) {
            mInternalSession = session;
        }

        /**
         * This is called after the class is initialized, at which point it knows it can call
         * getLocale() etc...
         */
        public abstract void onCreate();

        /**
         * Get suggestions for specified text in TextInfo.
         * This function will run on the incoming IPC thread.
         * So, this is not called on the main thread,
         * but will be called in series on another thread.
         * @param textInfo the text metadata
         * @param suggestionsLimit the maximum number of suggestions to be returned
         * @return SuggestionsInfo which contains suggestions for textInfo
         */
        public abstract SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit);

        /**
         * A batch process of onGetSuggestions.
         * This function will run on the incoming IPC thread.
         * So, this is not called on the main thread,
         * but will be called in series on another thread.
         * @param textInfos an array of the text metadata
         * @param suggestionsLimit the maximum number of suggestions to be returned
         * @param sequentialWords true if textInfos can be treated as sequential words.
         * @return an array of {@link SentenceSuggestionsInfo} returned by
         * {@link SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
         */
        public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
                int suggestionsLimit, boolean sequentialWords) {
            final int length = textInfos.length;
            final SuggestionsInfo[] retval = new SuggestionsInfo[length];
            for (int i = 0; i < length; ++i) {
                retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit);
                retval[i].setCookieAndSequence(
                        textInfos[i].getCookie(), textInfos[i].getSequence());
            }
            return retval;
        }

        /**
         * Get sentence suggestions for specified texts in an array of TextInfo.
         * The default implementation splits the input text to words and returns
         * {@link SentenceSuggestionsInfo} which contains suggestions for each word.
         * This function will run on the incoming IPC thread.
         * So, this is not called on the main thread,
         * but will be called in series on another thread.
         * When you override this method, make sure that suggestionsLimit is applied to suggestions
         * that share the same start position and length.
         * @param textInfos an array of the text metadata
         * @param suggestionsLimit the maximum number of suggestions to be returned
         * @return an array of {@link SentenceSuggestionsInfo} returned by
         * {@link SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
         */
        public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple(TextInfo[] textInfos,
                int suggestionsLimit) {
            if (textInfos == null || textInfos.length == 0) {
                return SentenceLevelAdapter.EMPTY_SENTENCE_SUGGESTIONS_INFOS;
            }
            if (DBG) {
                Log.d(TAG, "onGetSentenceSuggestionsMultiple: + " + textInfos.length + ", "
                        + suggestionsLimit);
            }
            if (mSentenceLevelAdapter == null) {
                synchronized(this) {
                    if (mSentenceLevelAdapter == null) {
                        final String localeStr = getLocale();
                        if (!TextUtils.isEmpty(localeStr)) {
                            mSentenceLevelAdapter = new SentenceLevelAdapter(new Locale(localeStr));
                        }
                    }
                }
            }
            if (mSentenceLevelAdapter == null) {
                return SentenceLevelAdapter.EMPTY_SENTENCE_SUGGESTIONS_INFOS;
            }
            final int infosSize = textInfos.length;
            final SentenceSuggestionsInfo[] retval = new SentenceSuggestionsInfo[infosSize];
            for (int i = 0; i < infosSize; ++i) {
                final SentenceLevelAdapter.SentenceTextInfoParams textInfoParams =
                        mSentenceLevelAdapter.getSplitWords(textInfos[i]);
                final ArrayList<SentenceLevelAdapter.SentenceWordItem> mItems =
                        textInfoParams.mItems;
                final int itemsSize = mItems.size();
                final TextInfo[] splitTextInfos = new TextInfo[itemsSize];
                for (int j = 0; j < itemsSize; ++j) {
                    splitTextInfos[j] = mItems.get(j).mTextInfo;
                }
                retval[i] = SentenceLevelAdapter.reconstructSuggestions(
                        textInfoParams, onGetSuggestionsMultiple(
                                splitTextInfos, suggestionsLimit, true));
            }
            return retval;
        }

        /**
         * Request to abort all tasks executed in SpellChecker.
         * This function will run on the incoming IPC thread.
         * So, this is not called on the main thread,
         * but will be called in series on another thread.
         */
        public void onCancel() {}

        /**
         * Request to close this session.
         * This function will run on the incoming IPC thread.
         * So, this is not called on the main thread,
         * but will be called in series on another thread.
         */
        public void onClose() {}

        /**
         * @return Locale for this session
         */
        public String getLocale() {
            return mInternalSession.getLocale();
        }

        /**
         * @return Bundle for this session
         */
        public Bundle getBundle() {
            return mInternalSession.getBundle();
        }
    }

    // Preventing from exposing ISpellCheckerSession.aidl, create an internal class.
    private static class InternalISpellCheckerSession extends ISpellCheckerSession.Stub {
        private ISpellCheckerSessionListener mListener;
        private final Session mSession;
        private final String mLocale;
        private final Bundle mBundle;

        public InternalISpellCheckerSession(String locale, ISpellCheckerSessionListener listener,
                Bundle bundle, Session session) {
            mListener = listener;
            mSession = session;
            mLocale = locale;
            mBundle = bundle;
            session.setInternalISpellCheckerSession(this);
        }

        @Override
        public void onGetSuggestionsMultiple(
                TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mListener.onGetSuggestions(
                        mSession.onGetSuggestionsMultiple(
                                textInfos, suggestionsLimit, sequentialWords));
            } catch (RemoteException e) {
            } finally {
                Process.setThreadPriority(pri);
            }
        }

        @Override
        public void onGetSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
            try {
                mListener.onGetSentenceSuggestions(
                        mSession.onGetSentenceSuggestionsMultiple(textInfos, suggestionsLimit));
            } catch (RemoteException e) {
            }
        }

        @Override
        public void onCancel() {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mSession.onCancel();
            } finally {
                Process.setThreadPriority(pri);
            }
        }

        @Override
        public void onClose() {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mSession.onClose();
            } finally {
                Process.setThreadPriority(pri);
                mListener = null;
            }
        }

        public String getLocale() {
            return mLocale;
        }

        public Bundle getBundle() {
            return mBundle;
        }
    }

    private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub {
        private final WeakReference<SpellCheckerService> mInternalServiceRef;

        public SpellCheckerServiceBinder(SpellCheckerService service) {
            mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
        }

        @Override
        public ISpellCheckerSession getISpellCheckerSession(
                String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
            final SpellCheckerService service = mInternalServiceRef.get();
            if (service == null) return null;
            final Session session = service.createSession();
            final InternalISpellCheckerSession internalSession =
                    new InternalISpellCheckerSession(locale, listener, bundle, session);
            session.onCreate();
            return internalSession;
        }
    }

    /**
     * Adapter class to accommodate word level spell checking APIs to sentence level spell checking
     * APIs used in
     * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)}
     */
    private static class SentenceLevelAdapter {
        public static final SentenceSuggestionsInfo[] EMPTY_SENTENCE_SUGGESTIONS_INFOS =
                new SentenceSuggestionsInfo[] {};
        private static final SuggestionsInfo EMPTY_SUGGESTIONS_INFO = new SuggestionsInfo(0, null);
        /**
         * Container for split TextInfo parameters
         */
        public static class SentenceWordItem {
            public final TextInfo mTextInfo;
            public final int mStart;
            public final int mLength;
            public SentenceWordItem(TextInfo ti, int start, int end) {
                mTextInfo = ti;
                mStart = start;
                mLength = end - start;
            }
        }

        /**
         * Container for originally queried TextInfo and parameters
         */
        public static class SentenceTextInfoParams {
            final TextInfo mOriginalTextInfo;
            final ArrayList<SentenceWordItem> mItems;
            final int mSize;
            public SentenceTextInfoParams(TextInfo ti, ArrayList<SentenceWordItem> items) {
                mOriginalTextInfo = ti;
                mItems = items;
                mSize = items.size();
            }
        }

        private final WordIterator mWordIterator;
        public SentenceLevelAdapter(Locale locale) {
            mWordIterator = new WordIterator(locale);
        }

        private SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) {
            final WordIterator wordIterator = mWordIterator;
            final CharSequence originalText = originalTextInfo.getText();
            final int cookie = originalTextInfo.getCookie();
            final int start = 0;
            final int end = originalText.length();
            final ArrayList<SentenceWordItem> wordItems = new ArrayList<SentenceWordItem>();
            wordIterator.setCharSequence(originalText, 0, originalText.length());
            int wordEnd = wordIterator.following(start);
            int wordStart = wordIterator.getBeginning(wordEnd);
            if (DBG) {
                Log.d(TAG, "iterator: break: ---- 1st word start = " + wordStart + ", end = "
                        + wordEnd + "\n" + originalText);
            }
            while (wordStart <= end && wordEnd != BreakIterator.DONE
                    && wordStart != BreakIterator.DONE) {
                if (wordEnd >= start && wordEnd > wordStart) {
                    final CharSequence query = originalText.subSequence(wordStart, wordEnd);
                    final TextInfo ti = new TextInfo(query, 0, query.length(), cookie,
                            query.hashCode());
                    wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd));
                    if (DBG) {
                        Log.d(TAG, "Adapter: word (" + (wordItems.size() - 1) + ") " + query);
                    }
                }
                wordEnd = wordIterator.following(wordEnd);
                if (wordEnd == BreakIterator.DONE) {
                    break;
                }
                wordStart = wordIterator.getBeginning(wordEnd);
            }
            return new SentenceTextInfoParams(originalTextInfo, wordItems);
        }

        public static SentenceSuggestionsInfo reconstructSuggestions(
                SentenceTextInfoParams originalTextInfoParams, SuggestionsInfo[] results) {
            if (results == null || results.length == 0) {
                return null;
            }
            if (DBG) {
                Log.w(TAG, "Adapter: onGetSuggestions: got " + results.length);
            }
            if (originalTextInfoParams == null) {
                if (DBG) {
                    Log.w(TAG, "Adapter: originalTextInfoParams is null.");
                }
                return null;
            }
            final int originalCookie = originalTextInfoParams.mOriginalTextInfo.getCookie();
            final int originalSequence =
                    originalTextInfoParams.mOriginalTextInfo.getSequence();

            final int querySize = originalTextInfoParams.mSize;
            final int[] offsets = new int[querySize];
            final int[] lengths = new int[querySize];
            final SuggestionsInfo[] reconstructedSuggestions = new SuggestionsInfo[querySize];
            for (int i = 0; i < querySize; ++i) {
                final SentenceWordItem item = originalTextInfoParams.mItems.get(i);
                SuggestionsInfo result = null;
                for (int j = 0; j < results.length; ++j) {
                    final SuggestionsInfo cur = results[j];
                    if (cur != null && cur.getSequence() == item.mTextInfo.getSequence()) {
                        result = cur;
                        result.setCookieAndSequence(originalCookie, originalSequence);
                        break;
                    }
                }
                offsets[i] = item.mStart;
                lengths[i] = item.mLength;
                reconstructedSuggestions[i] = result != null ? result : EMPTY_SUGGESTIONS_INFO;
                if (DBG) {
                    final int size = reconstructedSuggestions[i].getSuggestionsCount();
                    Log.w(TAG, "reconstructedSuggestions(" + i + ")" + size + ", first = "
                            + (size > 0 ? reconstructedSuggestions[i].getSuggestionAt(0)
                                    : "<none>") + ", offset = " + offsets[i] + ", length = "
                            + lengths[i]);
                }
            }
            return new SentenceSuggestionsInfo(reconstructedSuggestions, offsets, lengths);
        }
    }
}
