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

import com.android.internal.util.XmlUtils;

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

import android.content.ComponentName;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.util.Slog;

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

public class PreferredComponent {
    public final int mMatch;
    public final ComponentName mComponent;

    private final String[] mSetPackages;
    private final String[] mSetClasses;
    private final String[] mSetComponents;
    private final String mShortComponent;
    private String mParseError;

    private final Callbacks mCallbacks;

    public interface Callbacks {
        public boolean onReadTag(String tagName, XmlPullParser parser)
                throws XmlPullParserException, IOException;
    }

    public PreferredComponent(Callbacks callbacks, int match, ComponentName[] set,
            ComponentName component) {
        mCallbacks = callbacks;
        mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
        mComponent = component;
        mShortComponent = component.flattenToShortString();
        mParseError = null;
        if (set != null) {
            final int N = set.length;
            String[] myPackages = new String[N];
            String[] myClasses = new String[N];
            String[] myComponents = new String[N];
            for (int i=0; i<N; i++) {
                ComponentName cn = set[i];
                if (cn == null) {
                    mSetPackages = null;
                    mSetClasses = null;
                    mSetComponents = null;
                    return;
                }
                myPackages[i] = cn.getPackageName().intern();
                myClasses[i] = cn.getClassName().intern();
                myComponents[i] = cn.flattenToShortString().intern();
            }
            mSetPackages = myPackages;
            mSetClasses = myClasses;
            mSetComponents = myComponents;
        } else {
            mSetPackages = null;
            mSetClasses = null;
            mSetComponents = null;
        }
    }

    public PreferredComponent(Callbacks callbacks, XmlPullParser parser)
            throws XmlPullParserException, IOException {
        mCallbacks = callbacks;
        mShortComponent = parser.getAttributeValue(null, "name");
        mComponent = ComponentName.unflattenFromString(mShortComponent);
        if (mComponent == null) {
            mParseError = "Bad activity name " + mShortComponent;
        }
        String matchStr = parser.getAttributeValue(null, "match");
        mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
        String setCountStr = parser.getAttributeValue(null, "set");
        int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;

        String[] myPackages = setCount > 0 ? new String[setCount] : null;
        String[] myClasses = setCount > 0 ? new String[setCount] : null;
        String[] myComponents = setCount > 0 ? new String[setCount] : null;

        int setPos = 0;

        int outerDepth = parser.getDepth();
        int type;
        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
               && (type != XmlPullParser.END_TAG
                       || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG
                    || type == XmlPullParser.TEXT) {
                continue;
            }

            String tagName = parser.getName();
            //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth="
            //        + parser.getDepth() + " tag=" + tagName);
            if (tagName.equals("set")) {
                String name = parser.getAttributeValue(null, "name");
                if (name == null) {
                    if (mParseError == null) {
                        mParseError = "No name in set tag in preferred activity "
                            + mShortComponent;
                    }
                } else if (setPos >= setCount) {
                    if (mParseError == null) {
                        mParseError = "Too many set tags in preferred activity "
                            + mShortComponent;
                    }
                } else {
                    ComponentName cn = ComponentName.unflattenFromString(name);
                    if (cn == null) {
                        if (mParseError == null) {
                            mParseError = "Bad set name " + name + " in preferred activity "
                                + mShortComponent;
                        }
                    } else {
                        myPackages[setPos] = cn.getPackageName();
                        myClasses[setPos] = cn.getClassName();
                        myComponents[setPos] = name;
                        setPos++;
                    }
                }
                XmlUtils.skipCurrentTag(parser);
            } else if (!mCallbacks.onReadTag(tagName, parser)) {
                Slog.w("PreferredComponent", "Unknown element: " + parser.getName());
                XmlUtils.skipCurrentTag(parser);
            }
        }

        if (setPos != setCount) {
            if (mParseError == null) {
                mParseError = "Not enough set tags (expected " + setCount
                    + " but found " + setPos + ") in " + mShortComponent;
            }
        }

        mSetPackages = myPackages;
        mSetClasses = myClasses;
        mSetComponents = myComponents;
    }

    public String getParseError() {
        return mParseError;
    }

    public void writeToXml(XmlSerializer serializer) throws IOException {
        final int NS = mSetClasses != null ? mSetClasses.length : 0;
        serializer.attribute(null, "name", mShortComponent);
        if (mMatch != 0) {
            serializer.attribute(null, "match", Integer.toHexString(mMatch));
        }
        serializer.attribute(null, "set", Integer.toString(NS));
        for (int s=0; s<NS; s++) {
            serializer.startTag(null, "set");
            serializer.attribute(null, "name", mSetComponents[s]);
            serializer.endTag(null, "set");
        }
    }

    public boolean sameSet(List<ResolveInfo> query, int priority) {
        if (mSetPackages == null) return false;
        final int NQ = query.size();
        final int NS = mSetPackages.length;
        int numMatch = 0;
        for (int i=0; i<NQ; i++) {
            ResolveInfo ri = query.get(i);
            if (ri.priority != priority) continue;
            ActivityInfo ai = ri.activityInfo;
            boolean good = false;
            for (int j=0; j<NS; j++) {
                if (mSetPackages[j].equals(ai.packageName)
                        && mSetClasses[j].equals(ai.name)) {
                    numMatch++;
                    good = true;
                    break;
                }
            }
            if (!good) return false;
        }
        return numMatch == NS;
    }

    public void dump(PrintWriter out, String prefix, Object ident) {
        out.print(prefix); out.print(
                Integer.toHexString(System.identityHashCode(ident)));
                out.print(' ');
                out.print(mComponent.flattenToShortString());
                out.print(" match=0x");
                out.println( Integer.toHexString(mMatch));
        if (mSetComponents != null) {
            out.print(prefix); out.println("  Selected from:");
            for (int i=0; i<mSetComponents.length; i++) {
                out.print(prefix); out.print("    ");
                        out.println(mSetComponents[i]);
            }
        }
    }
}
