/*
 * 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;

import com.android.inputmethod.dictionarypack.DictionaryPackConstants;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.util.Log;

/**
 * Receives broadcasts pertaining to dictionary management and takes the appropriate action.
 *
 * This object receives three types of broadcasts.
 * - Package installed/added. When a dictionary provider application is added or removed, we
 * need to query the dictionaries.
 * - New dictionary broadcast. The dictionary provider broadcasts new dictionary availability. When
 * this happens, we need to re-query the dictionaries.
 * - Unknown client. If the dictionary provider is in urgent need of data about some client that
 * it does not know, it sends this broadcast. When we receive this, we need to tell the dictionary
 * provider about ourselves. This happens when the settings for the dictionary pack are accessed,
 * but Latin IME never got a chance to register itself.
 */
public final class DictionaryPackInstallBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = DictionaryPackInstallBroadcastReceiver.class.getSimpleName();

    final LatinIME mService;

    public DictionaryPackInstallBroadcastReceiver() {
        // This empty constructor is necessary for the system to instantiate this receiver.
        // This happens when the dictionary pack says it can't find a record for our client,
        // which happens when the dictionary pack settings are called before the keyboard
        // was ever started once.
        Log.i(TAG, "Latin IME dictionary broadcast receiver instantiated from the framework.");
        mService = null;
    }

    public DictionaryPackInstallBroadcastReceiver(final LatinIME service) {
        mService = service;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        final PackageManager manager = context.getPackageManager();

        // We need to reread the dictionary if a new dictionary package is installed.
        if (action.equals(Intent.ACTION_PACKAGE_ADDED)) {
            if (null == mService) {
                Log.e(TAG, "Called with intent " + action + " but we don't know the service: this "
                        + "should never happen");
                return;
            }
            final Uri packageUri = intent.getData();
            if (null == packageUri) return; // No package name : we can't do anything
            final String packageName = packageUri.getSchemeSpecificPart();
            if (null == packageName) return;
            // TODO: do this in a more appropriate place
            TargetPackageInfoGetterTask.removeCachedPackageInfo(packageName);
            final PackageInfo packageInfo;
            try {
                packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_PROVIDERS);
            } catch (android.content.pm.PackageManager.NameNotFoundException e) {
                return; // No package info : we can't do anything
            }
            final ProviderInfo[] providers = packageInfo.providers;
            if (null == providers) return; // No providers : it is not a dictionary.

            // Search for some dictionary pack in the just-installed package. If found, reread.
            for (ProviderInfo info : providers) {
                if (DictionaryPackConstants.AUTHORITY.equals(info.authority)) {
                    mService.resetSuggestMainDict();
                    return;
                }
            }
            // If we come here none of the authorities matched the one we searched for.
            // We can exit safely.
            return;
        } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
                && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
            if (null == mService) {
                Log.e(TAG, "Called with intent " + action + " but we don't know the service: this "
                        + "should never happen");
                return;
            }
            // When the dictionary package is removed, we need to reread dictionary (to use the
            // next-priority one, or stop using a dictionary at all if this was the only one,
            // since this is the user request).
            // If we are replacing the package, we will receive ADDED right away so no need to
            // remove the dictionary at the moment, since we will do it when we receive the
            // ADDED broadcast.

            // TODO: Only reload dictionary on REMOVED when the removed package is the one we
            // read dictionary from?
            mService.resetSuggestMainDict();
        } else if (action.equals(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)) {
            if (null == mService) {
                Log.e(TAG, "Called with intent " + action + " but we don't know the service: this "
                        + "should never happen");
                return;
            }
            mService.resetSuggestMainDict();
        } else if (action.equals(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT)) {
            if (null != mService) {
                // Careful! This is returning if the service is NOT null. This is because we
                // should come here instantiated by the framework in reaction to a broadcast of
                // the above action, so we should gave gone through the no-args constructor.
                Log.e(TAG, "Called with intent " + action + " but we have a reference to the "
                        + "service: this should never happen");
                return;
            }
            // The dictionary provider does not know about some client. We check that it's really
            // us that it needs to know about, and if it's the case, we register with the provider.
            final String wantedClientId =
                    intent.getStringExtra(DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA);
            final String myClientId = context.getString(R.string.dictionary_pack_client_id);
            if (!wantedClientId.equals(myClientId)) return; // Not for us
            BinaryDictionaryFileDumper.initializeClientRecordHelper(context, myClientId);
        }
    }
}
