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

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.Xml;

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

/**
 * This class is used to specify meta information of a spell checker.
 */
public final class SpellCheckerInfo implements Parcelable {
    private static final String TAG = SpellCheckerInfo.class.getSimpleName();
    private final ResolveInfo mService;
    private final String mId;
    private final int mLabel;

    /**
     * The spell checker setting activity's name, used by the system settings to
     * launch the setting activity.
     */
    private final String mSettingsActivityName;

    /**
     * The array of subtypes.
     */
    private final ArrayList<SpellCheckerSubtype> mSubtypes = new ArrayList<>();

    /**
     * Constructor.
     * @hide
     */
    public SpellCheckerInfo(Context context, ResolveInfo service)
            throws XmlPullParserException, IOException {
        mService = service;
        ServiceInfo si = service.serviceInfo;
        mId = new ComponentName(si.packageName, si.name).flattenToShortString();

        final PackageManager pm = context.getPackageManager();
        int label = 0;
        String settingsActivityComponent = null;

        XmlResourceParser parser = null;
        try {
            parser = si.loadXmlMetaData(pm, SpellCheckerSession.SERVICE_META_DATA);
            if (parser == null) {
                throw new XmlPullParserException("No "
                        + SpellCheckerSession.SERVICE_META_DATA + " meta-data");
            }

            final Resources res = pm.getResourcesForApplication(si.applicationInfo);
            final AttributeSet attrs = Xml.asAttributeSet(parser);
            int type;
            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                    && type != XmlPullParser.START_TAG) {
            }

            final String nodeName = parser.getName();
            if (!"spell-checker".equals(nodeName)) {
                throw new XmlPullParserException(
                        "Meta-data does not start with spell-checker tag");
            }

            TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.SpellChecker);
            label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
            settingsActivityComponent = sa.getString(
                    com.android.internal.R.styleable.SpellChecker_settingsActivity);
            sa.recycle();

            final int depth = parser.getDepth();
            // Parse all subtypes
            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
                    && type != XmlPullParser.END_DOCUMENT) {
                if (type == XmlPullParser.START_TAG) {
                    final String subtypeNodeName = parser.getName();
                    if (!"subtype".equals(subtypeNodeName)) {
                        throw new XmlPullParserException(
                                "Meta-data in spell-checker does not start with subtype tag");
                    }
                    final TypedArray a = res.obtainAttributes(
                            attrs, com.android.internal.R.styleable.SpellChecker_Subtype);
                    SpellCheckerSubtype subtype = new SpellCheckerSubtype(
                            a.getResourceId(com.android.internal.R.styleable
                                    .SpellChecker_Subtype_label, 0),
                            a.getString(com.android.internal.R.styleable
                                    .SpellChecker_Subtype_subtypeLocale),
                            a.getString(com.android.internal.R.styleable
                                    .SpellChecker_Subtype_languageTag),
                            a.getString(com.android.internal.R.styleable
                                    .SpellChecker_Subtype_subtypeExtraValue),
                            a.getInt(com.android.internal.R.styleable
                                    .SpellChecker_Subtype_subtypeId, 0));
                    mSubtypes.add(subtype);
                }
            }
        } catch (Exception e) {
            Slog.e(TAG, "Caught exception: " + e);
            throw new XmlPullParserException(
                    "Unable to create context for: " + si.packageName);
        } finally {
            if (parser != null) parser.close();
        }
        mLabel = label;
        mSettingsActivityName = settingsActivityComponent;
    }

    /**
     * Constructor.
     * @hide
     */
    public SpellCheckerInfo(Parcel source) {
        mLabel = source.readInt();
        mId = source.readString();
        mSettingsActivityName = source.readString();
        mService = ResolveInfo.CREATOR.createFromParcel(source);
        source.readTypedList(mSubtypes, SpellCheckerSubtype.CREATOR);
    }

    /**
     * Return a unique ID for this spell checker.  The ID is generated from
     * the package and class name implementing the method.
     */
    public String getId() {
        return mId;
    }

    /**
     * Return the component of the service that implements.
     */
    public ComponentName getComponent() {
        return new ComponentName(
                mService.serviceInfo.packageName, mService.serviceInfo.name);
    }

    /**
     * Return the .apk package that implements this.
     */
    public String getPackageName() {
        return mService.serviceInfo.packageName;
    }

    /**
     * Used to package this object into a {@link Parcel}.
     *
     * @param dest The {@link Parcel} to be written.
     * @param flags The flags used for parceling.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mLabel);
        dest.writeString(mId);
        dest.writeString(mSettingsActivityName);
        mService.writeToParcel(dest, flags);
        dest.writeTypedList(mSubtypes);
    }


    /**
     * Used to make this class parcelable.
     */
    public static final Parcelable.Creator<SpellCheckerInfo> CREATOR
            = new Parcelable.Creator<SpellCheckerInfo>() {
        @Override
        public SpellCheckerInfo createFromParcel(Parcel source) {
            return new SpellCheckerInfo(source);
        }

        @Override
        public SpellCheckerInfo[] newArray(int size) {
            return new SpellCheckerInfo[size];
        }
    };

    /**
     * Load the user-displayed label for this spell checker.
     *
     * @param pm Supply a PackageManager used to load the spell checker's resources.
     */
    public CharSequence loadLabel(PackageManager pm) {
        if (mLabel == 0 || pm == null) return "";
        return pm.getText(getPackageName(), mLabel, mService.serviceInfo.applicationInfo);
    }

    /**
     * Load the user-displayed icon for this spell checker.
     *
     * @param pm Supply a PackageManager used to load the spell checker's resources.
     */
    public Drawable loadIcon(PackageManager pm) {
        return mService.loadIcon(pm);
    }


    /**
     * Return the raw information about the Service implementing this
     * spell checker.  Do not modify the returned object.
     */
    public ServiceInfo getServiceInfo() {
        return mService.serviceInfo;
    }

    /**
     * Return the class name of an activity that provides a settings UI.
     * You can launch this activity be starting it with
     * an {@link android.content.Intent} whose action is MAIN and with an
     * explicit {@link android.content.ComponentName}
     * composed of {@link #getPackageName} and the class name returned here.
     *
     * <p>A null will be returned if there is no settings activity.
     */
    public String getSettingsActivity() {
        return mSettingsActivityName;
    }

    /**
     * Return the count of the subtypes.
     */
    public int getSubtypeCount() {
        return mSubtypes.size();
    }

    /**
     * Return the subtype at the specified index.
     *
     * @param index the index of the subtype to return.
     */
    public SpellCheckerSubtype getSubtypeAt(int index) {
        return mSubtypes.get(index);
    }

    /**
     * Used to make this class parcelable.
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * @hide
     */
    public void dump(final PrintWriter pw, final String prefix) {
        pw.println(prefix + "mId=" + mId);
        pw.println(prefix + "mSettingsActivityName=" + mSettingsActivityName);
        pw.println(prefix + "Service:");
        mService.dump(new PrintWriterPrinter(pw), prefix + "  ");
        final int N = getSubtypeCount();
        for (int i = 0; i < N; i++) {
            final SpellCheckerSubtype st = getSubtypeAt(i);
            pw.println(prefix + "  " + "Subtype #" + i + ":");
            pw.println(prefix + "    " + "locale=" + st.getLocale()
                    + " languageTag=" + st.getLanguageTag());
            pw.println(prefix + "    " + "extraValue=" + st.getExtraValue());
        }
    }
}
