/*
 * 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.inputmethod.latin.spellcheck;

import android.util.Log;

import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;

import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * A blocking queue that creates dictionaries up to a certain limit as necessary.
 * As a deadlock-detecting device, if waiting for more than TIMEOUT = 3 seconds, we
 * will clear the queue and generate its contents again. This is transparent for
 * the client code, but may help with sloppy clients.
 */
@SuppressWarnings("serial")
public final class DictionaryPool extends LinkedBlockingQueue<DictAndProximity> {
    private final static String TAG = DictionaryPool.class.getSimpleName();
    // How many seconds we wait for a dictionary to become available. Past this delay, we give up in
    // fear some bug caused a deadlock, and reset the whole pool.
    private final static int TIMEOUT = 3;
    private final AndroidSpellCheckerService mService;
    private final int mMaxSize;
    private final Locale mLocale;
    private int mSize;
    private volatile boolean mClosed;
    final static ArrayList<SuggestedWordInfo> noSuggestions = CollectionUtils.newArrayList();
    private final static DictAndProximity dummyDict = new DictAndProximity(
            new Dictionary(Dictionary.TYPE_MAIN) {
                @Override
                public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
                        final String prevWord, final ProximityInfo proximityInfo) {
                    return noSuggestions;
                }
                @Override
                public boolean isValidWord(final String word) {
                    // This is never called. However if for some strange reason it ever gets
                    // called, returning true is less destructive (it will not underline the
                    // word in red).
                    return true;
                }
            }, null);

    static public boolean isAValidDictionary(final DictAndProximity dictInfo) {
        return null != dictInfo && dummyDict != dictInfo;
    }

    public DictionaryPool(final int maxSize, final AndroidSpellCheckerService service,
            final Locale locale) {
        super();
        mMaxSize = maxSize;
        mService = service;
        mLocale = locale;
        mSize = 0;
        mClosed = false;
    }

    @Override
    public DictAndProximity poll(final long timeout, final TimeUnit unit)
            throws InterruptedException {
        final DictAndProximity dict = poll();
        if (null != dict) return dict;
        synchronized(this) {
            if (mSize >= mMaxSize) {
                // Our pool is already full. Wait until some dictionary is ready, or TIMEOUT
                // expires to avoid a deadlock.
                final DictAndProximity result = super.poll(timeout, unit);
                if (null == result) {
                    Log.e(TAG, "Deadlock detected ! Resetting dictionary pool");
                    clear();
                    mSize = 1;
                    return mService.createDictAndProximity(mLocale);
                } else {
                    return result;
                }
            } else {
                ++mSize;
                return mService.createDictAndProximity(mLocale);
            }
        }
    }

    // Convenience method
    public DictAndProximity pollWithDefaultTimeout() {
        try {
            return poll(TIMEOUT, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return null;
        }
    }

    public void close() {
        synchronized(this) {
            mClosed = true;
            for (DictAndProximity dict : this) {
                dict.mDictionary.close();
            }
            clear();
        }
    }

    @Override
    public boolean offer(final DictAndProximity dict) {
        if (mClosed) {
            dict.mDictionary.close();
            return super.offer(dummyDict);
        } else {
            return super.offer(dict);
        }
    }
}
