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

import android.annotation.TargetApi;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.Context;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.support.annotation.VisibleForTesting;
import android.support.v4.util.ArrayMap;
import android.support.v4.util.ArraySet;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.SparseArray;

import com.android.contacts.R;
import com.android.contacts.compat.CompatUtils;
import com.android.contacts.model.SimCard;
import com.android.contacts.model.SimContact;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.PermissionsUtil;
import com.android.contacts.util.SharedPreferenceUtil;

import com.google.common.base.Joiner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Provides data access methods for loading contacts from a SIM card and and migrating these
 * SIM contacts to a CP2 account.
 */
public class SimContactDaoImpl extends SimContactDao {
    private static final String TAG = "SimContactDao";

    // Maximum number of SIM contacts to import in a single ContentResolver.applyBatch call.
    // This is necessary to avoid TransactionTooLargeException when there are a large number of
    // contacts. This has been tested on Nexus 6 NME70B and is probably be conservative enough
    // to work on any phone.
    private static final int IMPORT_MAX_BATCH_SIZE = 300;

    // How many SIM contacts to consider in a single query. This prevents hitting the SQLite
    // query parameter limit.
    static final int QUERY_MAX_BATCH_SIZE = 100;

    @VisibleForTesting
    public static final Uri ICC_CONTENT_URI = Uri.parse("content://icc/adn");

    public static String _ID = BaseColumns._ID;
    public static String NAME = "name";
    public static String NUMBER = "number";
    public static String EMAILS = "emails";

    private final Context mContext;
    private final ContentResolver mResolver;
    private final TelephonyManager mTelephonyManager;

    public SimContactDaoImpl(Context context) {
        mContext = context;
        mResolver = context.getContentResolver();
        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    }

    public Context getContext() {
        return mContext;
    }

    @Override
    public boolean canReadSimContacts() {
        // Require SIM_STATE_READY because the TelephonyManager methods related to SIM require
        // this state
        return hasTelephony() && hasPermissions() &&
                mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY;
    }

    @Override
    public List<SimCard> getSimCards() {
        if (!canReadSimContacts()) {
            return Collections.emptyList();
        }
        final List<SimCard> sims = CompatUtils.isMSIMCompatible() ?
                getSimCardsFromSubscriptions() :
                Collections.singletonList(SimCard.create(mTelephonyManager,
                        mContext.getString(R.string.single_sim_display_label)));
        return SharedPreferenceUtil.restoreSimStates(mContext, sims);
    }

    @Override
    public ArrayList<SimContact> loadContactsForSim(SimCard sim) {
        if (sim.hasValidSubscriptionId()) {
            return loadSimContacts(sim.getSubscriptionId());
        }
        return loadSimContacts();
    }

    public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
        return loadFrom(ICC_CONTENT_URI.buildUpon()
                .appendPath("subId")
                .appendPath(String.valueOf(subscriptionId))
                .build());
    }

    public ArrayList<SimContact> loadSimContacts() {
        return loadFrom(ICC_CONTENT_URI);
    }

    @Override
    public ContentProviderResult[] importContacts(List<SimContact> contacts,
            AccountWithDataSet targetAccount)
            throws RemoteException, OperationApplicationException {
        if (contacts.size() < IMPORT_MAX_BATCH_SIZE) {
            return importBatch(contacts, targetAccount);
        }
        final List<ContentProviderResult> results = new ArrayList<>();
        for (int i = 0; i < contacts.size(); i += IMPORT_MAX_BATCH_SIZE) {
            results.addAll(Arrays.asList(importBatch(
                    contacts.subList(i, Math.min(contacts.size(), i + IMPORT_MAX_BATCH_SIZE)),
                    targetAccount)));
        }
        return results.toArray(new ContentProviderResult[results.size()]);
    }

    public void persistSimState(SimCard sim) {
        SharedPreferenceUtil.persistSimStates(mContext, Collections.singletonList(sim));
    }

    @Override
    public void persistSimStates(List<SimCard> simCards) {
        SharedPreferenceUtil.persistSimStates(mContext, simCards);
    }

    @Override
    public SimCard getSimBySubscriptionId(int subscriptionId) {
        final List<SimCard> sims = SharedPreferenceUtil.restoreSimStates(mContext, getSimCards());
        if (subscriptionId == SimCard.NO_SUBSCRIPTION_ID && !sims.isEmpty()) {
            return sims.get(0);
        }
        for (SimCard sim : getSimCards()) {
            if (sim.getSubscriptionId() == subscriptionId) {
                return sim;
            }
        }
        return null;
    }

    /**
     * Finds SIM contacts that exist in CP2 and associates the account of the CP2 contact with
     * the SIM contact
     */
    public Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
            List<SimContact> contacts) {
        final Map<AccountWithDataSet, Set<SimContact>> result = new ArrayMap<>();
        for (int i = 0; i < contacts.size(); i += QUERY_MAX_BATCH_SIZE) {
            findAccountsOfExistingSimContacts(
                    contacts.subList(i, Math.min(contacts.size(), i + QUERY_MAX_BATCH_SIZE)),
                    result);
        }
        return result;
    }

    private void findAccountsOfExistingSimContacts(List<SimContact> contacts,
            Map<AccountWithDataSet, Set<SimContact>> result) {
        final Map<Long, List<SimContact>> rawContactToSimContact = new HashMap<>();
        Collections.sort(contacts, SimContact.compareByPhoneThenName());

        final Cursor dataCursor = queryRawContactsForSimContacts(contacts);

        try {
            while (dataCursor.moveToNext()) {
                final String number = DataQuery.getPhoneNumber(dataCursor);
                final String name = DataQuery.getDisplayName(dataCursor);

                final int index = SimContact.findByPhoneAndName(contacts, number, name);
                if (index < 0) {
                    continue;
                }
                final SimContact contact = contacts.get(index);
                final long id = DataQuery.getRawContactId(dataCursor);
                if (!rawContactToSimContact.containsKey(id)) {
                    rawContactToSimContact.put(id, new ArrayList<SimContact>());
                }
                rawContactToSimContact.get(id).add(contact);
            }
        } finally {
            dataCursor.close();
        }

        final Cursor accountsCursor = queryAccountsOfRawContacts(rawContactToSimContact.keySet());
        try {
            while (accountsCursor.moveToNext()) {
                final AccountWithDataSet account = AccountQuery.getAccount(accountsCursor);
                final long id = AccountQuery.getId(accountsCursor);
                if (!result.containsKey(account)) {
                    result.put(account, new ArraySet<SimContact>());
                }
                for (SimContact contact : rawContactToSimContact.get(id)) {
                    result.get(account).add(contact);
                }
            }
        } finally {
            accountsCursor.close();
        }
    }


    private ContentProviderResult[] importBatch(List<SimContact> contacts,
            AccountWithDataSet targetAccount)
            throws RemoteException, OperationApplicationException {
        final ArrayList<ContentProviderOperation> ops =
                createImportOperations(contacts, targetAccount);
        return mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    private List<SimCard> getSimCardsFromSubscriptions() {
        final SubscriptionManager subscriptionManager = (SubscriptionManager)
                mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
        final List<SubscriptionInfo> subscriptions = subscriptionManager
                .getActiveSubscriptionInfoList();
        final ArrayList<SimCard> result = new ArrayList<>();
        for (SubscriptionInfo subscriptionInfo : subscriptions) {
            result.add(SimCard.create(subscriptionInfo));
        }
        return result;
    }

    private List<SimContact> getContactsForSim(SimCard sim) {
        final List<SimContact> contacts = sim.getContacts();
        return contacts != null ? contacts : loadContactsForSim(sim);
    }

    // See b/32831092
    // Sometimes the SIM contacts provider seems to get stuck if read from multiple threads
    // concurrently. So we just have a global lock around it to prevent potential issues.
    private static final Object SIM_READ_LOCK = new Object();
    private ArrayList<SimContact> loadFrom(Uri uri) {
        synchronized (SIM_READ_LOCK) {
            final Cursor cursor = mResolver.query(uri, null, null, null, null);

            try {
                return loadFromCursor(cursor);
            } finally {
                cursor.close();
            }
        }
    }

    private ArrayList<SimContact> loadFromCursor(Cursor cursor) {
        final int colId = cursor.getColumnIndex(_ID);
        final int colName = cursor.getColumnIndex(NAME);
        final int colNumber = cursor.getColumnIndex(NUMBER);
        final int colEmails = cursor.getColumnIndex(EMAILS);

        final ArrayList<SimContact> result = new ArrayList<>();

        while (cursor.moveToNext()) {
            final long id = cursor.getLong(colId);
            final String name = cursor.getString(colName);
            final String number = cursor.getString(colNumber);
            final String emails = cursor.getString(colEmails);

            final SimContact contact = new SimContact(id, name, number, parseEmails(emails));
            // Only include contact if it has some useful data
            if (contact.hasName() || contact.hasPhone() || contact.hasEmails()) {
                result.add(contact);
            }
        }
        return result;
    }

    private Cursor queryRawContactsForSimContacts(List<SimContact> contacts) {
        final StringBuilder selectionBuilder = new StringBuilder();

        int phoneCount = 0;
        int nameCount = 0;
        for (SimContact contact : contacts) {
            if (contact.hasPhone()) {
                phoneCount++;
            } else if (contact.hasName()) {
                nameCount++;
            }
        }
        List<String> selectionArgs = new ArrayList<>(phoneCount + 1);

        selectionBuilder.append('(');
        selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
        selectionArgs.add(Phone.CONTENT_ITEM_TYPE);

        selectionBuilder.append(Phone.NUMBER).append(" IN (")
                .append(Joiner.on(',').join(Collections.nCopies(phoneCount, '?')))
                .append(')');
        for (SimContact contact : contacts) {
            if (contact.hasPhone()) {
                selectionArgs.add(contact.getPhone());
            }
        }
        selectionBuilder.append(')');

        if (nameCount > 0) {
            selectionBuilder.append(" OR (");

            selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
            selectionArgs.add(StructuredName.CONTENT_ITEM_TYPE);

            selectionBuilder.append(Data.DISPLAY_NAME).append(" IN (")
                    .append(Joiner.on(',').join(Collections.nCopies(nameCount, '?')))
                    .append(')');
            for (SimContact contact : contacts) {
                if (!contact.hasPhone() && contact.hasName()) {
                    selectionArgs.add(contact.getName());
                }
            }
            selectionBuilder.append(')');
        }

        return mResolver.query(Data.CONTENT_URI.buildUpon()
                        .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
                        .build(),
                DataQuery.PROJECTION,
                selectionBuilder.toString(),
                selectionArgs.toArray(new String[selectionArgs.size()]),
                null);
    }

    private Cursor queryAccountsOfRawContacts(Set<Long> ids) {
        final StringBuilder selectionBuilder = new StringBuilder();

        final String[] args = new String[ids.size()];

        selectionBuilder.append(RawContacts._ID).append(" IN (")
                .append(Joiner.on(',').join(Collections.nCopies(args.length, '?')))
                .append(")");
        int i = 0;
        for (long id : ids) {
            args[i++] = String.valueOf(id);
        }
        return mResolver.query(RawContacts.CONTENT_URI,
                AccountQuery.PROJECTION,
                selectionBuilder.toString(),
                args,
                null);
    }

    private ArrayList<ContentProviderOperation> createImportOperations(List<SimContact> contacts,
            AccountWithDataSet targetAccount) {
        final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
        for (SimContact contact : contacts) {
            contact.appendCreateContactOperations(ops, targetAccount);
        }
        return ops;
    }

    private String[] parseEmails(String emails) {
        return !TextUtils.isEmpty(emails) ? emails.split(",") : null;
    }

    private boolean hasTelephony() {
        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
    }

    private boolean hasPermissions() {
        return PermissionsUtil.hasContactsPermissions(mContext) &&
                PermissionsUtil.hasPhonePermissions(mContext);
    }

    // TODO remove this class and the USE_FAKE_INSTANCE flag once this code is not under
    // active development or anytime after 3/1/2017
    public static class DebugImpl extends SimContactDaoImpl {

        private List<SimCard> mSimCards = new ArrayList<>();
        private SparseArray<SimCard> mCardsBySubscription = new SparseArray<>();

        public DebugImpl(Context context) {
            super(context);
        }

        public DebugImpl addSimCard(SimCard sim) {
            mSimCards.add(sim);
            mCardsBySubscription.put(sim.getSubscriptionId(), sim);
            return this;
        }

        @Override
        public List<SimCard> getSimCards() {
            return SharedPreferenceUtil.restoreSimStates(getContext(), mSimCards);
        }

        @Override
        public ArrayList<SimContact> loadContactsForSim(SimCard card) {
            return new ArrayList<>(card.getContacts());
        }

        @Override
        public boolean canReadSimContacts() {
            return true;
        }
    }

    // Query used for detecting existing contacts that may match a SimContact.
    private static final class DataQuery {

        public static final String[] PROJECTION = new String[] {
                Data.RAW_CONTACT_ID, Phone.NUMBER, Data.DISPLAY_NAME, Data.MIMETYPE
        };

        public static final int RAW_CONTACT_ID = 0;
        public static final int PHONE_NUMBER = 1;
        public static final int DISPLAY_NAME = 2;
        public static final int MIMETYPE = 3;

        public static long getRawContactId(Cursor cursor) {
            return cursor.getLong(RAW_CONTACT_ID);
        }

        public static String getPhoneNumber(Cursor cursor) {
            return isPhoneNumber(cursor) ? cursor.getString(PHONE_NUMBER) : null;
        }

        public static String getDisplayName(Cursor cursor) {
            return cursor.getString(DISPLAY_NAME);
        }

        public static boolean isPhoneNumber(Cursor cursor) {
            return Phone.CONTENT_ITEM_TYPE.equals(cursor.getString(MIMETYPE));
        }
    }

    private static final class AccountQuery {
        public static final String[] PROJECTION = new String[] {
                RawContacts._ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
                RawContacts.DATA_SET
        };

        public static long getId(Cursor cursor) {
            return cursor.getLong(0);
        }

        public static AccountWithDataSet getAccount(Cursor cursor) {
            return new AccountWithDataSet(cursor.getString(1), cursor.getString(2),
                    cursor.getString(3));
        }
    }
}
