/*
 * Copyright (C) 2009 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.contacts.common.model.account;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;

import com.android.contacts.common.model.dataitem.DataKind;
import com.google.common.annotations.VisibleForTesting;

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

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

/**
 * A general contacts account type descriptor.
 */
public class ExternalAccountType extends BaseAccountType {
    private static final String TAG = "ExternalAccountType";

    private static final String METADATA_CONTACTS = "android.provider.CONTACTS_STRUCTURE";

    private static final String TAG_CONTACTS_SOURCE_LEGACY = "ContactsSource";
    private static final String TAG_CONTACTS_ACCOUNT_TYPE = "ContactsAccountType";
    private static final String TAG_CONTACTS_DATA_KIND = "ContactsDataKind";
    private static final String TAG_EDIT_SCHEMA = "EditSchema";

    private static final String ATTR_EDIT_CONTACT_ACTIVITY = "editContactActivity";
    private static final String ATTR_CREATE_CONTACT_ACTIVITY = "createContactActivity";
    private static final String ATTR_INVITE_CONTACT_ACTIVITY = "inviteContactActivity";
    private static final String ATTR_INVITE_CONTACT_ACTION_LABEL = "inviteContactActionLabel";
    private static final String ATTR_VIEW_CONTACT_NOTIFY_SERVICE = "viewContactNotifyService";
    private static final String ATTR_VIEW_GROUP_ACTIVITY = "viewGroupActivity";
    private static final String ATTR_VIEW_GROUP_ACTION_LABEL = "viewGroupActionLabel";
    private static final String ATTR_VIEW_STREAM_ITEM_ACTIVITY = "viewStreamItemActivity";
    private static final String ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY =
            "viewStreamItemPhotoActivity";
    private static final String ATTR_DATA_SET = "dataSet";
    private static final String ATTR_EXTENSION_PACKAGE_NAMES = "extensionPackageNames";

    // The following attributes should only be set in non-sync-adapter account types.  They allow
    // for the account type and resource IDs to be specified without an associated authenticator.
    private static final String ATTR_ACCOUNT_TYPE = "accountType";
    private static final String ATTR_ACCOUNT_LABEL = "accountTypeLabel";
    private static final String ATTR_ACCOUNT_ICON = "accountTypeIcon";

    private final boolean mIsExtension;

    private String mEditContactActivityClassName;
    private String mCreateContactActivityClassName;
    private String mInviteContactActivity;
    private String mInviteActionLabelAttribute;
    private int mInviteActionLabelResId;
    private String mViewContactNotifyService;
    private String mViewGroupActivity;
    private String mViewGroupLabelAttribute;
    private int mViewGroupLabelResId;
    private String mViewStreamItemActivity;
    private String mViewStreamItemPhotoActivity;
    private List<String> mExtensionPackageNames;
    private String mAccountTypeLabelAttribute;
    private String mAccountTypeIconAttribute;
    private boolean mHasContactsMetadata;
    private boolean mHasEditSchema;

    public ExternalAccountType(Context context, String resPackageName, boolean isExtension) {
        this(context, resPackageName, isExtension, null);
    }

    /**
     * Constructor used for testing to initialize with any arbitrary XML.
     *
     * @param injectedMetadata If non-null, it'll be used to initialize the type.  Only set by
     *     tests.  If null, the metadata is loaded from the specified package.
     */
    ExternalAccountType(Context context, String packageName, boolean isExtension,
            XmlResourceParser injectedMetadata) {
        this.mIsExtension = isExtension;
        this.resourcePackageName = packageName;
        this.syncAdapterPackageName = packageName;

        final PackageManager pm = context.getPackageManager();
        final XmlResourceParser parser;
        if (injectedMetadata == null) {
            try {
                parser = loadContactsXml(context, packageName);
            } catch (NameNotFoundException e1) {
                // If the package name is not found, we can't initialize this account type.
                return;
            }
        } else {
            parser = injectedMetadata;
        }
        boolean needLineNumberInErrorLog = true;
        try {
            if (parser != null) {
                inflate(context, parser);
            }

            // Done parsing; line number no longer needed in error log.
            needLineNumberInErrorLog = false;
            if (mHasEditSchema) {
                checkKindExists(StructuredName.CONTENT_ITEM_TYPE);
                checkKindExists(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
                checkKindExists(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME);
                checkKindExists(Photo.CONTENT_ITEM_TYPE);
            } else {
                // Bring in name and photo from fallback source, which are non-optional
                addDataKindStructuredName(context);
                addDataKindDisplayName(context);
                addDataKindPhoneticName(context);
                addDataKindPhoto(context);
            }
        } catch (DefinitionException e) {
            final StringBuilder error = new StringBuilder();
            error.append("Problem reading XML");
            if (needLineNumberInErrorLog && (parser != null)) {
                error.append(" in line ");
                error.append(parser.getLineNumber());
            }
            error.append(" for external package ");
            error.append(packageName);

            Log.e(TAG, error.toString(), e);
            return;
        } finally {
            if (parser != null) {
                parser.close();
            }
        }

        mExtensionPackageNames = new ArrayList<String>();
        mInviteActionLabelResId = resolveExternalResId(context, mInviteActionLabelAttribute,
                syncAdapterPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL);
        mViewGroupLabelResId = resolveExternalResId(context, mViewGroupLabelAttribute,
                syncAdapterPackageName, ATTR_VIEW_GROUP_ACTION_LABEL);
        titleRes = resolveExternalResId(context, mAccountTypeLabelAttribute,
                syncAdapterPackageName, ATTR_ACCOUNT_LABEL);
        iconRes = resolveExternalResId(context, mAccountTypeIconAttribute,
                syncAdapterPackageName, ATTR_ACCOUNT_ICON);

        // If we reach this point, the account type has been successfully initialized.
        mIsInitialized = true;
    }

    /**
     * Returns the CONTACTS_STRUCTURE metadata (aka "contacts.xml") in the given apk package.
     *
     * Unfortunately, there's no public way to determine which service defines a sync service for
     * which account type, so this method looks through all services in the package, and just
     * returns the first CONTACTS_STRUCTURE metadata defined in any of them.
     *
     * Returns {@code null} if the package has no CONTACTS_STRUCTURE metadata.  In this case
     * the account type *will* be initialized with minimal configuration.
     *
     * On the other hand, if the package is not found, it throws a {@link NameNotFoundException},
     * in which case the account type will *not* be initialized.
     */
    private XmlResourceParser loadContactsXml(Context context, String resPackageName)
            throws NameNotFoundException {
        final PackageManager pm = context.getPackageManager();
        PackageInfo packageInfo = pm.getPackageInfo(resPackageName,
                PackageManager.GET_SERVICES|PackageManager.GET_META_DATA);
        for (ServiceInfo serviceInfo : packageInfo.services) {
            final XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm,
                    METADATA_CONTACTS);
            if (parser != null) {
                return parser;
            }
        }
        // Package was found, but that doesn't contain the CONTACTS_STRUCTURE metadata.
        return null;
    }

    private void checkKindExists(String mimeType) throws DefinitionException {
        if (getKindForMimetype(mimeType) == null) {
            throw new DefinitionException(mimeType + " must be supported");
        }
    }

    @Override
    public boolean isEmbedded() {
        return false;
    }

    @Override
    public boolean isExtension() {
        return mIsExtension;
    }

    @Override
    public boolean areContactsWritable() {
        return mHasEditSchema;
    }

    /**
     * Whether this account type has the android.provider.CONTACTS_STRUCTURE metadata xml.
     */
    public boolean hasContactsMetadata() {
        return mHasContactsMetadata;
    }

    @Override
    public String getEditContactActivityClassName() {
        return mEditContactActivityClassName;
    }

    @Override
    public String getCreateContactActivityClassName() {
        return mCreateContactActivityClassName;
    }

    @Override
    public String getInviteContactActivityClassName() {
        return mInviteContactActivity;
    }

    @Override
    protected int getInviteContactActionResId() {
        return mInviteActionLabelResId;
    }

    @Override
    public String getViewContactNotifyServiceClassName() {
        return mViewContactNotifyService;
    }

    @Override
    public String getViewGroupActivity() {
        return mViewGroupActivity;
    }

    @Override
    protected int getViewGroupLabelResId() {
        return mViewGroupLabelResId;
    }

    @Override
    public String getViewStreamItemActivity() {
        return mViewStreamItemActivity;
    }

    @Override
    public String getViewStreamItemPhotoActivity() {
        return mViewStreamItemPhotoActivity;
    }

    @Override
    public List<String> getExtensionPackageNames() {
        return mExtensionPackageNames;
    }

    /**
     * Inflate this {@link AccountType} from the given parser. This may only
     * load details matching the publicly-defined schema.
     */
    protected void inflate(Context context, XmlPullParser parser) throws DefinitionException {
        final AttributeSet attrs = Xml.asAttributeSet(parser);

        try {
            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG
                    && type != XmlPullParser.END_DOCUMENT) {
                // Drain comments and whitespace
            }

            if (type != XmlPullParser.START_TAG) {
                throw new IllegalStateException("No start tag found");
            }

            String rootTag = parser.getName();
            if (!TAG_CONTACTS_ACCOUNT_TYPE.equals(rootTag) &&
                    !TAG_CONTACTS_SOURCE_LEGACY.equals(rootTag)) {
                throw new IllegalStateException("Top level element must be "
                        + TAG_CONTACTS_ACCOUNT_TYPE + ", not " + rootTag);
            }

            mHasContactsMetadata = true;

            int attributeCount = parser.getAttributeCount();
            for (int i = 0; i < attributeCount; i++) {
                String attr = parser.getAttributeName(i);
                String value = parser.getAttributeValue(i);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, attr + "=" + value);
                }
                if (ATTR_EDIT_CONTACT_ACTIVITY.equals(attr)) {
                    mEditContactActivityClassName = value;
                } else if (ATTR_CREATE_CONTACT_ACTIVITY.equals(attr)) {
                    mCreateContactActivityClassName = value;
                } else if (ATTR_INVITE_CONTACT_ACTIVITY.equals(attr)) {
                    mInviteContactActivity = value;
                } else if (ATTR_INVITE_CONTACT_ACTION_LABEL.equals(attr)) {
                    mInviteActionLabelAttribute = value;
                } else if (ATTR_VIEW_CONTACT_NOTIFY_SERVICE.equals(attr)) {
                    mViewContactNotifyService = value;
                } else if (ATTR_VIEW_GROUP_ACTIVITY.equals(attr)) {
                    mViewGroupActivity = value;
                } else if (ATTR_VIEW_GROUP_ACTION_LABEL.equals(attr)) {
                    mViewGroupLabelAttribute = value;
                } else if (ATTR_VIEW_STREAM_ITEM_ACTIVITY.equals(attr)) {
                    mViewStreamItemActivity = value;
                } else if (ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY.equals(attr)) {
                    mViewStreamItemPhotoActivity = value;
                } else if (ATTR_DATA_SET.equals(attr)) {
                    dataSet = value;
                } else if (ATTR_EXTENSION_PACKAGE_NAMES.equals(attr)) {
                    mExtensionPackageNames.add(value);
                } else if (ATTR_ACCOUNT_TYPE.equals(attr)) {
                    accountType = value;
                } else if (ATTR_ACCOUNT_LABEL.equals(attr)) {
                    mAccountTypeLabelAttribute = value;
                } else if (ATTR_ACCOUNT_ICON.equals(attr)) {
                    mAccountTypeIconAttribute = value;
                } else {
                    Log.e(TAG, "Unsupported attribute " + attr);
                }
            }

            // Parse all children kinds
            final int startDepth = parser.getDepth();
            while (((type = parser.next()) != XmlPullParser.END_TAG
                        || parser.getDepth() > startDepth)
                    && type != XmlPullParser.END_DOCUMENT) {

                if (type != XmlPullParser.START_TAG || parser.getDepth() != startDepth + 1) {
                    continue; // Not a direct child tag
                }

                String tag = parser.getName();
                if (TAG_EDIT_SCHEMA.equals(tag)) {
                    mHasEditSchema = true;
                    parseEditSchema(context, parser, attrs);
                } else if (TAG_CONTACTS_DATA_KIND.equals(tag)) {
                    final TypedArray a = context.obtainStyledAttributes(attrs,
                            android.R.styleable.ContactsDataKind);
                    final DataKind kind = new DataKind();

                    kind.mimeType = a
                            .getString(android.R.styleable.ContactsDataKind_mimeType);
                    final String summaryColumn = a.getString(
                            android.R.styleable.ContactsDataKind_summaryColumn);
                    if (summaryColumn != null) {
                        // Inflate a specific column as summary when requested
                        kind.actionHeader = new SimpleInflater(summaryColumn);
                    }

                    final String detailColumn = a.getString(
                            android.R.styleable.ContactsDataKind_detailColumn);

                    if (detailColumn != null) {
                        // Inflate specific column as summary
                        kind.actionBody = new SimpleInflater(detailColumn);
                    }

                    a.recycle();

                    addKind(kind);
                }
            }
        } catch (XmlPullParserException e) {
            throw new DefinitionException("Problem reading XML", e);
        } catch (IOException e) {
            throw new DefinitionException("Problem reading XML", e);
        }
    }

    /**
     * Takes a string in the "@xxx/yyy" format and return the resource ID for the resource in
     * the resource package.
     *
     * If the argument is in the invalid format or isn't a resource name, it returns -1.
     *
     * @param context context
     * @param resourceName Resource name in the "@xxx/yyy" format, e.g. "@string/invite_lavbel"
     * @param packageName name of the package containing the resource.
     * @param xmlAttributeName attribute name which the resource came from.  Used for logging.
     */
    @VisibleForTesting
    static int resolveExternalResId(Context context, String resourceName,
            String packageName, String xmlAttributeName) {
        if (TextUtils.isEmpty(resourceName)) {
            return -1; // Empty text is okay.
        }
        if (resourceName.charAt(0) != '@') {
            Log.e(TAG, xmlAttributeName + " must be a resource name beginnig with '@'");
            return -1;
        }
        final String name = resourceName.substring(1);
        final Resources res;
        try {
             res = context.getPackageManager().getResourcesForApplication(packageName);
        } catch (NameNotFoundException e) {
            Log.e(TAG, "Unable to load package " + packageName);
            return -1;
        }
        final int resId = res.getIdentifier(name, null, packageName);
        if (resId == 0) {
            Log.e(TAG, "Unable to load " + resourceName + " from package " + packageName);
            return -1;
        }
        return resId;
    }
}
