/*
 * Copyright (C) 2015 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 android.provider.cts;

import junit.framework.Assert;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.provider.ContactsContract;
import android.provider.ContactsContract.AggregationExceptions;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.DisplayNameSources;
import android.provider.ContactsContract.RawContacts;
import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
import android.provider.cts.contacts.ContactUtil;
import android.test.AndroidTestCase;

/**
 * CTS tests for {@link DisplayNameSources#STRUCTURED_PHONETIC_NAME}.
 */
public class ContactsContract_StructuredPhoneticName extends AndroidTestCase {
    private ContentResolver mResolver;
    private ContactsContract_TestDataBuilder mBuilder;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mResolver = getContext().getContentResolver();
        ContentProviderClient provider =
                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
        mBuilder = new ContactsContract_TestDataBuilder(provider);
    }

    @Override
    protected void tearDown() throws Exception {
        mBuilder.cleanup();
        super.tearDown();
    }

    public void testPhoneticStructuredName() throws Exception {
        // Setup: contact with only phonetic name
        TestRawContact rawContact1 = mBuilder.newRawContact()
                .with(RawContacts.ACCOUNT_TYPE, "test_account")
                .with(RawContacts.ACCOUNT_NAME, "test_name")
                .insert();
        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                .with(StructuredName.PHONETIC_FAMILY_NAME, "phonetic name")
                .insert();
        rawContact1.load();
        name1.load();

        // Verify: DISPLAY_NAME_SOURCE notices that the StructuredName only has phonetic components
        TestContact contact = rawContact1.getContact().load();
        contact.assertColumn(Contacts.DISPLAY_NAME_SOURCE,
                DisplayNameSources.STRUCTURED_PHONETIC_NAME);
    }

    public void testPhoneticStructuredName_phoneticPriority1() throws Exception {
        // Setup: one raw contact has a complex phonetic name and the other a simple given name
        TestRawContact rawContact1 = mBuilder.newRawContact()
                .with(RawContacts.ACCOUNT_TYPE, "test_account")
                .with(RawContacts.ACCOUNT_NAME, "test_name")
                .insert();
        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                .with(StructuredName.GIVEN_NAME, "name")
                .insert();
        rawContact1.load();
        name1.load();

        TestRawContact rawContact2 = mBuilder.newRawContact()
                .with(RawContacts.ACCOUNT_TYPE, "test_account")
                .with(RawContacts.ACCOUNT_NAME, "test_name")
                .insert();
        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                .with(StructuredName.PHONETIC_FAMILY_NAME, "name phonetic")
                .insert();
        rawContact2.load();
        name2.load();

        // Execute: aggregate the two raw contacts together
        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
                rawContact1.getId(), rawContact2.getId());

        // Sanity check: two contacts are aggregated
        rawContact1.load();
        rawContact2.load();
        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());

        // Verify: the display name is taken from the name with more than phonetic components
        TestContact contact = rawContact2.getContact().load();
        contact.assertColumn(Contacts.DISPLAY_NAME, "name");
    }

    // Same as testPhoneticStructuredName_phoneticPriority1, but with setup order reversed
    public void testPhoneticStructuredName_phoneticPriority2() throws Exception {
        // Setup: one raw contact has a complex phonetic name and the other a simple given name
        TestRawContact rawContact2 = mBuilder.newRawContact()
                .with(RawContacts.ACCOUNT_TYPE, "test_account")
                .with(RawContacts.ACCOUNT_NAME, "test_name")
                .insert();
        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                .with(StructuredName.PHONETIC_FAMILY_NAME, "name phonetic")
                .insert();
        rawContact2.load();
        name2.load();

        TestRawContact rawContact1 = mBuilder.newRawContact()
                .with(RawContacts.ACCOUNT_TYPE, "test_account")
                .with(RawContacts.ACCOUNT_NAME, "test_name")
                .insert();
        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                .with(StructuredName.GIVEN_NAME, "name")
                .insert();
        rawContact1.load();
        name1.load();

        // Execute: aggregate the two raw contacts together
        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
                rawContact1.getId(), rawContact2.getId());

        // Sanity check: two contacts are aggregated
        rawContact1.load();
        rawContact2.load();
        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());

        // Verify: the display name is taken from the name with more than phonetic components
        TestContact contact = rawContact2.getContact().load();
        contact.assertColumn(Contacts.DISPLAY_NAME, "name");
    }
}
