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

import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncAdapterType;
import android.provider.ContactsContract;
import android.support.v4.util.ArraySet;
import android.text.TextUtils;
import android.util.Log;

import com.android.contacts.util.DeviceLocalAccountTypeFactory;
import com.android.contactsbind.ObjectFactory;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.android.contacts.util.DeviceLocalAccountTypeFactory.Util.isLocalAccountType;

/**
 * Provides access to {@link AccountType}s with contact data
 *
 * This class parses the contacts.xml for third-party accounts and caches the result.
 * This means that {@link AccountTypeProvider#getAccountTypes(String)}} should be called from a
 * background thread.
 */
public class AccountTypeProvider {
    private static final String TAG = "AccountTypeProvider";

    private final Context mContext;
    private final DeviceLocalAccountTypeFactory mLocalAccountTypeFactory;
    private final ImmutableMap<String, AuthenticatorDescription> mAuthTypes;

    private final ConcurrentMap<String, List<AccountType>> mCache = new ConcurrentHashMap<>();

    public AccountTypeProvider(Context context) {
        this(context,
                ObjectFactory.getDeviceLocalAccountTypeFactory(context),
                ContentResolver.getSyncAdapterTypes(),
                ((AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE))
                        .getAuthenticatorTypes());
    }

    public AccountTypeProvider(Context context, DeviceLocalAccountTypeFactory localTypeFactory,
            SyncAdapterType[] syncAdapterTypes,
            AuthenticatorDescription[] authenticatorDescriptions) {
        mContext = context;
        mLocalAccountTypeFactory = localTypeFactory;

        mAuthTypes = onlyContactSyncable(authenticatorDescriptions, syncAdapterTypes);
    }

    /**
     * Returns all account types associated with the provided type
     *
     * <p>There are many {@link AccountType}s for each accountType because {@AccountType} includes
     * a dataSet and accounts can declare extension packages in contacts.xml that provide additional
     * data sets for a particular type
     * </p>
     */
    public List<AccountType> getAccountTypes(String accountType) {
        // ConcurrentHashMap doesn't support null keys
        if (accountType == null) {
            AccountType type = mLocalAccountTypeFactory.getAccountType(accountType);
            // Just in case the DeviceLocalAccountTypeFactory doesn't handle the null type
            if (type == null) {
                type = new FallbackAccountType(mContext);
            }
            return Collections.singletonList(type);
        }

        List<AccountType> types = mCache.get(accountType);
        if (types == null) {
            types = loadTypes(accountType);
            mCache.put(accountType, types);
        }
        return types;
    }

    public boolean hasTypeForAccount(AccountWithDataSet account) {
        return getTypeForAccount(account) != null;
    }

    public boolean hasTypeWithDataset(String type, String dataSet) {
        // getAccountTypes() never returns null
        final List<AccountType> accountTypes = getAccountTypes(type);
        for (AccountType accountType : accountTypes) {
            if (Objects.equal(accountType.dataSet, dataSet)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the AccountType with the matching type and dataSet or null if no account with those
     * members exists
     */
    public AccountType getType(String type, String dataSet) {
        final List<AccountType> accountTypes = getAccountTypes(type);
        for (AccountType accountType : accountTypes) {
            if (Objects.equal(accountType.dataSet, dataSet)) {
                return accountType;
            }
        }
        return null;
    }

    /**
     * Returns the AccountType for a particular account or null if no account type exists for the
     * account
     */
    public AccountType getTypeForAccount(AccountWithDataSet account) {
        return getType(account.type, account.dataSet);
    }

    public boolean shouldUpdate(AuthenticatorDescription[] auths, SyncAdapterType[] syncTypes) {
        Map<String, AuthenticatorDescription> contactsAuths = onlyContactSyncable(auths, syncTypes);
        if (!contactsAuths.keySet().equals(mAuthTypes.keySet())) {
            return false;
        }
        for (AuthenticatorDescription auth : contactsAuths.values()) {
            if (!deepEquals(mAuthTypes.get(auth.type), auth)) {
                return false;
            }
        }
        return true;
    }

    private List<AccountType> loadTypes(String type) {
        final AuthenticatorDescription auth = mAuthTypes.get(type);
        if (auth == null) {
            return Collections.emptyList();
        }

        AccountType accountType;
        if (GoogleAccountType.ACCOUNT_TYPE.equals(type)) {
            accountType = new GoogleAccountType(mContext, auth.packageName);
        } else if (ExchangeAccountType.isExchangeType(type)) {
            accountType = new ExchangeAccountType(mContext, auth.packageName, type);
        } else if (SamsungAccountType.isSamsungAccountType(mContext, type,
                auth.packageName)) {
            accountType = new SamsungAccountType(mContext, auth.packageName, type);
        } else if (!ExternalAccountType.hasContactsXml(mContext, auth.packageName)
                && isLocalAccountType(mLocalAccountTypeFactory, type)) {
            accountType = mLocalAccountTypeFactory.getAccountType(type);
        } else {
            Log.d(TAG, "Registering external account type=" + type
                    + ", packageName=" + auth.packageName);
            accountType = new ExternalAccountType(mContext, auth.packageName, false);
        }
        if (!accountType.isInitialized()) {
            if (accountType.isEmbedded()) {
                throw new IllegalStateException("Problem initializing embedded type "
                        + accountType.getClass().getCanonicalName());
            } else {
                // Skip external account types that couldn't be initialized
                return Collections.emptyList();
            }
        }

        accountType.initializeFieldsFromAuthenticator(auth);

        final ImmutableList.Builder<AccountType> result = ImmutableList.builder();
        result.add(accountType);

        for (String extensionPackage : accountType.getExtensionPackageNames()) {
            final ExternalAccountType extensionType =
                    new ExternalAccountType(mContext, extensionPackage, true);
            if (!extensionType.isInitialized()) {
                // Skip external account types that couldn't be initialized.
                continue;
            }
            if (!extensionType.hasContactsMetadata()) {
                Log.w(TAG, "Skipping extension package " + extensionPackage + " because"
                        + " it doesn't have the CONTACTS_STRUCTURE metadata");
                continue;
            }
            if (TextUtils.isEmpty(extensionType.accountType)) {
                Log.w(TAG, "Skipping extension package " + extensionPackage + " because"
                        + " the CONTACTS_STRUCTURE metadata doesn't have the accountType"
                        + " attribute");
                continue;
            }
            if (Objects.equal(extensionType.accountType, type)) {
                Log.w(TAG, "Skipping extension package " + extensionPackage + " because"
                        + " the account type + " + extensionType.accountType +
                        " doesn't match expected type " + type);
                continue;
            }
            Log.d(TAG, "Registering extension package account type="
                    + accountType.accountType + ", dataSet=" + accountType.dataSet
                    + ", packageName=" + extensionPackage);

            result.add(extensionType);
        }
        return result.build();
    }

    private static ImmutableMap<String, AuthenticatorDescription> onlyContactSyncable(
            AuthenticatorDescription[] auths, SyncAdapterType[] syncTypes) {
        final Set<String> mContactSyncableTypes = new ArraySet<>();
        for (SyncAdapterType type : syncTypes) {
            if (type.authority.equals(ContactsContract.AUTHORITY)) {
                mContactSyncableTypes.add(type.accountType);
            }
        }

        final ImmutableMap.Builder<String, AuthenticatorDescription> builder =
                ImmutableMap.builder();
        for (AuthenticatorDescription auth : auths) {
            if (mContactSyncableTypes.contains(auth.type)) {
                builder.put(auth.type, auth);
            }
        }
        return builder.build();
    }

    /**
     * Compares all fields in auth1 and auth2
     *
     * <p>By default {@link AuthenticatorDescription#equals(Object)} only checks the type</p>
     */
    private boolean deepEquals(AuthenticatorDescription auth1, AuthenticatorDescription auth2) {
        return Objects.equal(auth1, auth2) &&
                Objects.equal(auth1.packageName, auth2.packageName) &&
                auth1.labelId == auth2.labelId &&
                auth1.iconId == auth2.iconId &&
                auth1.smallIconId == auth2.smallIconId &&
                auth1.accountPreferencesId == auth2.accountPreferencesId &&
                auth1.customTokens == auth2.customTokens;
    }

}
