/*
 * Copyright (C) 2011 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.editor;

import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.test.mocks.MockAccountTypeManager;
import com.google.common.collect.Sets;

import java.util.Collection;
import java.util.Set;

/**
 * Test case for {@link ContactEditorUtils}.
 *
 * adb shell am instrument -w -e class com.android.contacts.editor.ContactEditorUtilsTest \
       com.android.contacts.tests/android.test.InstrumentationTestRunner
 */
@SmallTest
public class ContactEditorUtilsTest extends AndroidTestCase {
    private MockAccountTypeManager mAccountTypes;
    private ContactEditorUtils mTarget;

    private static final MockAccountType TYPE1 = new MockAccountType("type1", null, true);
    private static final MockAccountType TYPE2 = new MockAccountType("type2", null, true);
    private static final MockAccountType TYPE2EX = new MockAccountType("type2", "ext", true);

    // Only type 3 is "readonly".
    private static final MockAccountType TYPE3 = new MockAccountType("type3", null, false);

    private static final AccountWithDataSet ACCOUNT_1_A = new AccountWithDataSet(
            "a", TYPE1.accountType, TYPE1.dataSet);
    private static final AccountWithDataSet ACCOUNT_1_B = new AccountWithDataSet(
            "b", TYPE1.accountType, TYPE1.dataSet);

    private static final AccountWithDataSet ACCOUNT_2_A = new AccountWithDataSet(
            "a", TYPE2.accountType, TYPE2.dataSet);
    private static final AccountWithDataSet ACCOUNT_2EX_A = new AccountWithDataSet(
            "a", TYPE2EX.accountType, TYPE2EX.dataSet);

    private static final AccountWithDataSet ACCOUNT_3_C = new AccountWithDataSet(
            "c", TYPE3.accountType, TYPE3.dataSet);

    @Override
    protected void setUp() throws Exception {
        // Initialize with 0 types, 0 accounts.
        mAccountTypes = new MockAccountTypeManager(new AccountType[] {},
                new AccountWithDataSet[] {});
        mTarget = new ContactEditorUtils(getContext(), mAccountTypes);

        // Clear the preferences.
        mTarget.cleanupForTest();
    }

    private void setAccountTypes(AccountType... types) {
        mAccountTypes.mTypes = types;
    }

    private void setAccounts(AccountWithDataSet... accounts) {
        mAccountTypes.mAccounts = accounts;
    }

    public void testGetWritableAccountTypeStrings() {
        String[] types;

        // 0 writable types
        setAccountTypes();

        types = mTarget.getWritableAccountTypeStrings();
        MoreAsserts.assertEquals(types, new String[0]);

        // 1 writable type
        setAccountTypes(TYPE1);

        types = mTarget.getWritableAccountTypeStrings();
        MoreAsserts.assertEquals(Sets.newHashSet(TYPE1.accountType), Sets.newHashSet(types));

        // 2 writable types
        setAccountTypes(TYPE1, TYPE2EX);

        types = mTarget.getWritableAccountTypeStrings();
        MoreAsserts.assertEquals(Sets.newHashSet(TYPE1.accountType, TYPE2EX.accountType),
                Sets.newHashSet(types));

        // 3 writable types + 1 readonly type
        setAccountTypes(TYPE1, TYPE2, TYPE2EX, TYPE3);

        types = mTarget.getWritableAccountTypeStrings();
        MoreAsserts.assertEquals(
                Sets.newHashSet(TYPE1.accountType, TYPE2.accountType, TYPE2EX.accountType),
                Sets.newHashSet(types));
    }

    /**
     * Test for
     * - {@link ContactEditorUtils#saveDefaultAccount}
     * - {@link ContactEditorUtils#getOnlyOrDefaultAccount}
     */
    public void testSaveDefaultAccount() {
        // Use these account types here.
        setAccountTypes(TYPE1, TYPE2);

        mTarget.saveDefaultAccount(null);
        assertNull(mTarget.getOnlyOrDefaultAccount());

        mTarget.saveDefaultAccount(ACCOUNT_1_A);
        assertEquals(ACCOUNT_1_A, mTarget.getOnlyOrDefaultAccount());
    }

    /**
     * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with
     * 0 accounts.
     */
    public void testShouldShowAccountChangedNotification_0Accounts() {
        setAccountTypes(TYPE1);

        // First launch -- always true.
        assertTrue(mTarget.shouldShowAccountChangedNotification());

        // We show the notification here, and user clicked "add account"
        setAccounts(ACCOUNT_1_A);

        // Now we open the contact editor with the new account.

        // When closing the editor, we save the default account.
        mTarget.saveDefaultAccount(ACCOUNT_1_A);

        // Next time the user creates a contact, we don't show the notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // User added a new writable account, ACCOUNT_1_B.
        setAccounts(ACCOUNT_1_A, ACCOUNT_1_B);

        // Since default account is still ACCOUNT_1_A, we don't show the notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // User saved a new contact.  We update the account list and the default account.
        mTarget.saveDefaultAccount(ACCOUNT_1_B);

        // User created another contact.  Now we don't show the notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // User installed a new contact sync adapter...

        // Added a new account type: TYPE2, and the TYPE2EX extension.
        setAccountTypes(TYPE1, TYPE2, TYPE2EX);
        // Add new accounts: ACCOUNT_2_A, ACCOUNT_2EX_A.
        setAccounts(ACCOUNT_1_A, ACCOUNT_1_B, ACCOUNT_2_A, ACCOUNT_2EX_A);

        // New added account but default account is still not changed, so no notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // User saves a new contact, with a different default account.
        mTarget.saveDefaultAccount(ACCOUNT_2_A);

        // Next time user creates a contact, no notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // Remove ACCOUNT_2EX_A.
        setAccountTypes(TYPE1, TYPE2, TYPE2EX);
        setAccounts(ACCOUNT_1_A, ACCOUNT_1_B, ACCOUNT_2_A);

        // ACCOUNT_2EX_A was not default, so no notification either.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // Remove ACCOUNT_1_B, which is default.
        setAccountTypes(TYPE1, TYPE2, TYPE2EX);
        setAccounts(ACCOUNT_1_A, ACCOUNT_1_B);

        // Now we show the notification.
        assertTrue(mTarget.shouldShowAccountChangedNotification());

        // Do not save the default account, and add a new account now.
        setAccountTypes(TYPE1, TYPE2, TYPE2EX);
        setAccounts(ACCOUNT_1_A, ACCOUNT_1_B, ACCOUNT_2EX_A);

        // No default account, so show notification.
        assertTrue(mTarget.shouldShowAccountChangedNotification());
    }

    /**
     * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with
     * 1 accounts.
     */
    public void testShouldShowAccountChangedNotification_1Account() {
        setAccountTypes(TYPE1, TYPE2);
        setAccounts(ACCOUNT_1_A);

        // Always returns false when 1 writable account.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // User saves a new contact.
        mTarget.saveDefaultAccount(ACCOUNT_1_A);

        // Next time, no notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // The rest is the same...
    }

    /**
     * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with
     * 0 accounts, and the user selected "local only".
     */
    public void testShouldShowAccountChangedNotification_0Account_localOnly() {
        setAccountTypes(TYPE1);

        // First launch -- always true.
        assertTrue(mTarget.shouldShowAccountChangedNotification());

        // We show the notification here, and user clicked "keep local" and saved an contact.
        mTarget.saveDefaultAccount(AccountWithDataSet.getNullAccount());

        // Now there are no accounts, and default account is null.

        // The user created another contact, but this we shouldn't show the notification.
        assertFalse(mTarget.shouldShowAccountChangedNotification());
    }

    public void testShouldShowAccountChangedNotification_sanity_check() {
        // Prepare 1 account and save it as the default.
        setAccountTypes(TYPE1);
        setAccounts(ACCOUNT_1_A);

        mTarget.saveDefaultAccount(ACCOUNT_1_A);

        // Right after a save, the dialog shouldn't show up.
        assertFalse(mTarget.shouldShowAccountChangedNotification());

        // Remove the default account to emulate broken preferences.
        mTarget.removeDefaultAccountForTest();

        // The dialog shouldn't show up.
        // The logic is, if there's a writable account, we'll pick it as default
        assertFalse(mTarget.shouldShowAccountChangedNotification());
    }

    private static <T> Set<T> toSet(Collection<T> collection) {
        Set<T> ret = Sets.newHashSet();
        ret.addAll(collection);
        return ret;
    }

    private static class MockAccountType extends AccountType {
        private boolean mAreContactsWritable;

        public MockAccountType(String accountType, String dataSet, boolean areContactsWritable) {
            this.accountType = accountType;
            this.dataSet = dataSet;
            mAreContactsWritable = areContactsWritable;
        }

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

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