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

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 {
    private static final String TAG_SET = "set";
    private static final String ATTR_ALWAYS = "always"; // boolean
    private static final String ATTR_MATCH = "match"; // number
    private static final String ATTR_NAME = "name"; // component name
    private static final String ATTR_SET = "set"; // number

    public final int mMatch;
    public final ComponentName mComponent;
    // Whether this is to be the one that's always chosen. If false, it's the most recently chosen.
    public boolean mAlways;

    final String[] mSetPackages;
    final String[] mSetClasses;
    final String[] mSetComponents;
    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, boolean always) {
        mCallbacks = callbacks;
        mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
        mComponent = component;
        mAlways = always;
        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();
            }
            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, ATTR_NAME);
        mComponent = ComponentName.unflattenFromString(mShortComponent);
        if (mComponent == null) {
            mParseError = "Bad activity name " + mShortComponent;
        }
        String matchStr = parser.getAttributeValue(null, ATTR_MATCH);
        mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
        String setCountStr = parser.getAttributeValue(null, ATTR_SET);
        int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
        String alwaysStr = parser.getAttributeValue(null, ATTR_ALWAYS);
        mAlways = alwaysStr != null ? Boolean.parseBoolean(alwaysStr) : true;

        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(TAG_SET)) {
                String name = parser.getAttributeValue(null, ATTR_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, boolean full) throws IOException {
        final int NS = mSetClasses != null ? mSetClasses.length : 0;
        serializer.attribute(null, ATTR_NAME, mShortComponent);
        if (full) {
            if (mMatch != 0) {
                serializer.attribute(null, ATTR_MATCH, Integer.toHexString(mMatch));
            }
            serializer.attribute(null, ATTR_ALWAYS, Boolean.toString(mAlways));
            serializer.attribute(null, ATTR_SET, Integer.toString(NS));
            for (int s=0; s<NS; s++) {
                serializer.startTag(null, TAG_SET);
                serializer.attribute(null, ATTR_NAME, mSetComponents[s]);
                serializer.endTag(null, TAG_SET);
            }
        }
    }

    public boolean sameSet(List<ResolveInfo> query) {
        if (mSetPackages == null) {
            return query == null;
        }
        if (query == 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);
            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 boolean sameSet(ComponentName[] comps) {
        if (mSetPackages == null) return false;
        final int NQ = comps.length;
        final int NS = mSetPackages.length;
        int numMatch = 0;
        for (int i=0; i<NQ; i++) {
            ComponentName cn = comps[i];
            boolean good = false;
            for (int j=0; j<NS; j++) {
                if (mSetPackages[j].equals(cn.getPackageName())
                        && mSetClasses[j].equals(cn.getClassName())) {
                    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.println(mShortComponent);
        out.print(prefix); out.print(" mMatch=0x");
                out.print(Integer.toHexString(mMatch));
                out.print(" mAlways="); out.println(mAlways);
        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]);
            }
        }
    }
}
