/*
 * Copyright (C) 2010 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.exchange.provider;

import com.android.email.R;
import com.android.email.Utility;
import com.android.email.VendorPolicyLoader;
import com.android.email.mail.PackedString;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.exchange.EasSyncService;
import com.android.exchange.provider.GalResult.GalData;

import android.accounts.AccountManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Binder;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Directory;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts.Data;
import android.text.TextUtils;

import java.util.HashMap;
import java.util.List;

/**
 * ExchangeDirectoryProvider provides real-time data from the Exchange server; at the moment, it is
 * used solely to provide GAL (Global Address Lookup) service to email address adapters
 */
public class ExchangeDirectoryProvider extends ContentProvider {
    public static final String EXCHANGE_GAL_AUTHORITY = "com.android.exchange.directory.provider";

    private static final int DEFAULT_CONTACT_ID = 1;
    private static final int DEFAULT_LOOKUP_LIMIT = 20;

    private static final int GAL_BASE = 0;
    private static final int GAL_DIRECTORIES = GAL_BASE;
    private static final int GAL_FILTER = GAL_BASE + 1;
    private static final int GAL_CONTACT = GAL_BASE + 2;
    private static final int GAL_CONTACT_WITH_ID = GAL_BASE + 3;
    private static final int GAL_EMAIL_FILTER = GAL_BASE + 4;

    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    /*package*/ final HashMap<String, Long> mAccountIdMap = new HashMap<String, Long>();

    static {
        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "directories", GAL_DIRECTORIES);
        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/filter/*", GAL_FILTER);
        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/entities", GAL_CONTACT);
        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/#/entities",
                GAL_CONTACT_WITH_ID);
        sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "data/emails/filter/*", GAL_EMAIL_FILTER);
    }

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

    static class GalProjection {
        final int size;
        final HashMap<String, Integer> columnMap = new HashMap<String, Integer>();

        GalProjection(String[] projection) {
            size = projection.length;
            for (int i = 0; i < projection.length; i++) {
                columnMap.put(projection[i], i);
            }
        }
    }

    static class GalContactRow {
        private final GalProjection mProjection;
        private Object[] row;
        static long dataId = 1;

        GalContactRow(GalProjection projection, long contactId, String lookupKey,
                String accountName, String displayName) {
            this.mProjection = projection;
            row = new Object[projection.size];

            put(Contacts.Entity.CONTACT_ID, contactId);

            // We only have one raw contact per aggregate, so they can have the same ID
            put(Contacts.Entity.RAW_CONTACT_ID, contactId);
            put(Contacts.Entity.DATA_ID, dataId++);

            put(Contacts.DISPLAY_NAME, displayName);

            // TODO alternative display name
            put(Contacts.DISPLAY_NAME_ALTERNATIVE, displayName);

            put(RawContacts.ACCOUNT_TYPE, com.android.email.Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
            put(RawContacts.ACCOUNT_NAME, accountName);
            put(RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
            put(Data.IS_READ_ONLY, 1);
        }

        Object[] getRow () {
            return row;
        }

        void put(String columnName, Object value) {
            Integer integer = mProjection.columnMap.get(columnName);
            if (integer != null) {
                row[integer] = value;
            } else {
                System.out.println("Unsupported column: " + columnName);
            }
        }

        static void addEmailAddress(MatrixCursor cursor, GalProjection galProjection,
                long contactId, String lookupKey, String accountName, String displayName,
                String address) {
            if (!TextUtils.isEmpty(address)) {
                GalContactRow r = new GalContactRow(
                        galProjection, contactId, lookupKey, accountName, displayName);
                r.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
                r.put(Email.TYPE, Email.TYPE_WORK);
                r.put(Email.ADDRESS, address);
                cursor.addRow(r.getRow());
            }
        }

        static void addPhoneRow(MatrixCursor cursor, GalProjection projection, long contactId,
                String lookupKey, String accountName, String displayName, int type, String number) {
            if (!TextUtils.isEmpty(number)) {
                GalContactRow r = new GalContactRow(
                        projection, contactId, lookupKey, accountName, displayName);
                r.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
                r.put(Phone.TYPE, type);
                r.put(Phone.NUMBER, number);
                cursor.addRow(r.getRow());
            }
        }

        public static void addNameRow(MatrixCursor cursor, GalProjection galProjection,
                long contactId, String lookupKey, String accountName, String displayName,
                String firstName, String lastName) {
            GalContactRow r = new GalContactRow(
                    galProjection, contactId, lookupKey, accountName, displayName);
            r.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
            r.put(StructuredName.GIVEN_NAME, firstName);
            r.put(StructuredName.FAMILY_NAME, lastName);
            r.put(StructuredName.DISPLAY_NAME, displayName);
            cursor.addRow(r.getRow());
        }
    }

    /**
     * Find the record id of an Account, given its name (email address)
     * @param accountName the name of the account
     * @return the record id of the Account, or -1 if not found
     */
    /*package*/ long getAccountIdByName(Context context, String accountName) {
        Long accountId = mAccountIdMap.get(accountName);
        if (accountId == null) {
            accountId = Utility.getFirstRowLong(context, Account.CONTENT_URI,
                    EmailContent.ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?",
                    new String[] {accountName}, null, EmailContent.ID_PROJECTION_COLUMN , -1L);
            if (accountId != -1) {
                mAccountIdMap.put(accountName, accountId);
            }
        }
        return accountId;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        int match = sURIMatcher.match(uri);
        MatrixCursor cursor;
        Object[] row;
        PackedString ps;
        String lookupKey;

        switch (match) {
            case GAL_DIRECTORIES: {
                // Assuming that GAL can be used with all exchange accounts
                android.accounts.Account[] accounts = AccountManager.get(getContext())
                        .getAccountsByType(com.android.email.Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
                cursor = new MatrixCursor(projection);
                if (accounts != null) {
                    for (android.accounts.Account account : accounts) {
                        row = new Object[projection.length];

                        for (int i = 0; i < projection.length; i++) {
                            String column = projection[i];
                            if (column.equals(Directory.ACCOUNT_NAME)) {
                                row[i] = account.name;
                            } else if (column.equals(Directory.ACCOUNT_TYPE)) {
                                row[i] = account.type;
                            } else if (column.equals(Directory.TYPE_RESOURCE_ID)) {
                                if (VendorPolicyLoader.getInstance(getContext())
                                        .useAlternateExchangeStrings()) {
                                    row[i] = R.string.exchange_name_alternate;
                                } else {
                                    row[i] = R.string.exchange_name;
                                }
                            } else if (column.equals(Directory.DISPLAY_NAME)) {
                                row[i] = account.name;
                            } else if (column.equals(Directory.EXPORT_SUPPORT)) {
                                row[i] = Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY;
                            } else if (column.equals(Directory.SHORTCUT_SUPPORT)) {
                                row[i] = Directory.SHORTCUT_SUPPORT_FULL;
                            }
                        }
                        cursor.addRow(row);
                    }
                }
                return cursor;
            }

            case GAL_FILTER:
            case GAL_EMAIL_FILTER: {
                String filter = uri.getLastPathSegment();
                // We should have at least two characters before doing a GAL search
                if (filter == null || filter.length() < 2) {
                    return null;
                }

                String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
                if (accountName == null) {
                    return null;
                }

                // Enforce a limit on the number of lookup responses
                String limitString = uri.getQueryParameter(ContactsContract.LIMIT_PARAM_KEY);
                int limit = DEFAULT_LOOKUP_LIMIT;
                if (limitString != null) {
                    try {
                        limit = Integer.parseInt(limitString);
                    } catch (NumberFormatException e) {
                        limit = 0;
                    }
                    if (limit <= 0) {
                        throw new IllegalArgumentException("Limit not valid: " + limitString);
                    }
                }

                long callingId = Binder.clearCallingIdentity();
                try {
                    // Find the account id to pass along to EasSyncService
                    long accountId = getAccountIdByName(getContext(), accountName);
                    if (accountId == -1) {
                        // The account was deleted?
                        return null;
                    }

                    // Get results from the Exchange account
                    GalResult galResult = EasSyncService.searchGal(getContext(), accountId,
                            filter, limit);
                    if (galResult != null) {
                        return buildGalResultCursor(projection, galResult);
                    }
                } finally {
                    Binder.restoreCallingIdentity(callingId);
                }
                break;
            }

            case GAL_CONTACT:
            case GAL_CONTACT_WITH_ID: {
                String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
                if (accountName == null) {
                    return null;
                }

                GalProjection galProjection = new GalProjection(projection);
                cursor = new MatrixCursor(projection);
                // Handle the decomposition of the key into rows suitable for CP2
                List<String> pathSegments = uri.getPathSegments();
                lookupKey = pathSegments.get(2);
                long contactId = (match == GAL_CONTACT_WITH_ID)
                        ? Long.parseLong(pathSegments.get(3))
                        : DEFAULT_CONTACT_ID;
                ps = new PackedString(lookupKey);
                String displayName = ps.get(GalData.DISPLAY_NAME);
                GalContactRow.addEmailAddress(cursor, galProjection, contactId, lookupKey,
                        accountName, displayName, ps.get(GalData.EMAIL_ADDRESS));
                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
                        displayName, displayName, Phone.TYPE_HOME, ps.get(GalData.HOME_PHONE));
                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
                        displayName, displayName, Phone.TYPE_WORK, ps.get(GalData.WORK_PHONE));
                GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName,
                        displayName, displayName, Phone.TYPE_MOBILE, ps.get(GalData.MOBILE_PHONE));
                GalContactRow.addNameRow(cursor, galProjection, contactId, accountName, displayName,
                        ps.get(GalData.FIRST_NAME), ps.get(GalData.LAST_NAME), displayName);
                return cursor;
            }
        }

        return null;
    }

    /*package*/ Cursor buildGalResultCursor(String[] projection, GalResult galResult) {
        int displayNameIndex = -1;
        int alternateDisplayNameIndex = -1;;
        int emailIndex = -1;
        int idIndex = -1;
        int lookupIndex = -1;

        for (int i = 0; i < projection.length; i++) {
            String column = projection[i];
            if (Contacts.DISPLAY_NAME.equals(column) ||
                    Contacts.DISPLAY_NAME_PRIMARY.equals(column)) {
                displayNameIndex = i;
            } else if (Contacts.DISPLAY_NAME_ALTERNATIVE.equals(column)) {
                alternateDisplayNameIndex = i;
            } else if (CommonDataKinds.Email.ADDRESS.equals(column)) {
                emailIndex = i;
            } else if (Contacts._ID.equals(column)) {
                idIndex = i;
            } else if (Contacts.LOOKUP_KEY.equals(column)) {
                lookupIndex = i;
            }
        }

        Object[] row = new Object[projection.length];

        /*
         * ContactsProvider will ensure that every request has a non-null projection.
         */
        MatrixCursor cursor = new MatrixCursor(projection);
        int count = galResult.galData.size();
        for (int i = 0; i < count; i++) {
            GalData galDataRow = galResult.galData.get(i);
            String firstName = galDataRow.get(GalData.FIRST_NAME);
            String lastName = galDataRow.get(GalData.LAST_NAME);
            String displayName = galDataRow.get(GalData.DISPLAY_NAME);
            // If we don't have a display name, try to create one using first and last name
            if (displayName == null) {
                if (firstName != null && lastName != null) {
                    displayName = firstName + " " + lastName;
                } else if (firstName != null) {
                    displayName = firstName;
                } else if (lastName != null) {
                    displayName = lastName;
                }
            }
            galDataRow.put(GalData.DISPLAY_NAME, displayName);

            if (displayNameIndex != -1) {
                row[displayNameIndex] = displayName;
            }
            if (alternateDisplayNameIndex != -1) {
                // Try to create an alternate display name, using first and last name
                // TODO: Check with Contacts team to make sure we're using this properly
                if (firstName != null && lastName != null) {
                    row[alternateDisplayNameIndex] = lastName + " " + firstName;
                } else {
                    row[alternateDisplayNameIndex] = displayName;
                }
            }
            if (emailIndex != -1) {
                row[emailIndex] = galDataRow.get(GalData.EMAIL_ADDRESS);
            }
            if (idIndex != -1) {
                row[idIndex] = i + 1;  // Let's be 1 based
            }
            if (lookupIndex != -1) {
                // We use the packed string as our lookup key; it contains ALL of the gal data
                // We do this because we are not able to provide a stable id to ContactsProvider
                row[lookupIndex] = Uri.encode(galDataRow.toPackedString());
            }
            cursor.addRow(row);
        }
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        int match = sURIMatcher.match(uri);
        switch (match) {
            case GAL_FILTER:
                return Contacts.CONTENT_ITEM_TYPE;
        }
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }
}
