/*
 * 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.common.model.account;

import android.accounts.Account;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;

import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.preference.ContactsPreferences;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Wrapper for an account that includes a data set (which may be null).
 */
public class AccountWithDataSet implements Parcelable {
    private static final String STRINGIFY_SEPARATOR = "\u0001";
    private static final String ARRAY_STRINGIFY_SEPARATOR = "\u0002";

    private static final Pattern STRINGIFY_SEPARATOR_PAT =
            Pattern.compile(Pattern.quote(STRINGIFY_SEPARATOR));
    private static final Pattern ARRAY_STRINGIFY_SEPARATOR_PAT =
            Pattern.compile(Pattern.quote(ARRAY_STRINGIFY_SEPARATOR));

    public final String name;
    public final String type;
    public final String dataSet;
    private final AccountTypeWithDataSet mAccountTypeWithDataSet;

    private static final String[] ID_PROJECTION = new String[] {BaseColumns._ID};
    private static final Uri RAW_CONTACTS_URI_LIMIT_1 = RawContacts.CONTENT_URI.buildUpon()
            .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, "1").build();

    public static final String LOCAL_ACCOUNT_SELECTION = RawContacts.ACCOUNT_TYPE + " IS NULL AND "
            + RawContacts.ACCOUNT_NAME + " IS NULL AND "
            + RawContacts.DATA_SET + " IS NULL";

    public AccountWithDataSet(String name, String type, String dataSet) {
        this.name = emptyToNull(name);
        this.type = emptyToNull(type);
        this.dataSet = emptyToNull(dataSet);
        mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet);
    }

    private static final String emptyToNull(String text) {
        return TextUtils.isEmpty(text) ? null : text;
    }

    public AccountWithDataSet(Parcel in) {
        this.name = in.readString();
        this.type = in.readString();
        this.dataSet = in.readString();
        mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet);
    }

    public boolean isNullAccount() {
        return name == null && type == null && dataSet == null;
    }

    public static AccountWithDataSet getNullAccount() {
        return new AccountWithDataSet(null, null, null);
    }

    public Account getAccountOrNull() {
        if (name != null && type != null) {
            return new Account(name, type);
        }
        return null;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(type);
        dest.writeString(dataSet);
    }

    // For Parcelable
    public static final Creator<AccountWithDataSet> CREATOR = new Creator<AccountWithDataSet>() {
        public AccountWithDataSet createFromParcel(Parcel source) {
            return new AccountWithDataSet(source);
        }

        public AccountWithDataSet[] newArray(int size) {
            return new AccountWithDataSet[size];
        }
    };

    public AccountTypeWithDataSet getAccountTypeWithDataSet() {
        return mAccountTypeWithDataSet;
    }

    /**
     * Return {@code true} if this account has any contacts in the database.
     * Touches DB.  Don't use in the UI thread.
     */
    public boolean hasData(Context context) {
        String selection;
        String[] args = null;
        if (isNullAccount()) {
            selection = LOCAL_ACCOUNT_SELECTION;
        } else {
            final String BASE_SELECTION =
                    RawContacts.ACCOUNT_TYPE + " = ?" + " AND " + RawContacts.ACCOUNT_NAME + " = ?";
            if (TextUtils.isEmpty(dataSet)) {
                selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " IS NULL";
                args = new String[] {type, name};
            } else {
                selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " = ?";
                args = new String[] {type, name, dataSet};
            }
        }
        selection += " AND " + RawContacts.DELETED + "=0";

        final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1,
                ID_PROJECTION, selection, args, null);
        if (c == null) return false;
        try {
            return c.moveToFirst();
        } finally {
            c.close();
        }
    }

    public boolean equals(Object obj) {
        if (obj instanceof AccountWithDataSet) {
            AccountWithDataSet other = (AccountWithDataSet) obj;
            return Objects.equal(name, other.name)
                    && Objects.equal(type, other.type)
                    && Objects.equal(dataSet, other.dataSet);
        }
        return false;
    }

    public int hashCode() {
        int result = 17;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (type != null ? type.hashCode() : 0);
        result = 31 * result + (dataSet != null ? dataSet.hashCode() : 0);
        return result;
    }

    public String toString() {
        return "AccountWithDataSet {name=" + name + ", type=" + type + ", dataSet=" + dataSet + "}";
    }

    private static StringBuilder addStringified(StringBuilder sb, AccountWithDataSet account) {
        if (!TextUtils.isEmpty(account.name)) sb.append(account.name);
        sb.append(STRINGIFY_SEPARATOR);
        if (!TextUtils.isEmpty(account.type)) sb.append(account.type);
        sb.append(STRINGIFY_SEPARATOR);
        if (!TextUtils.isEmpty(account.dataSet)) sb.append(account.dataSet);

        return sb;
    }

    /**
     * Pack the instance into a string.
     */
    public String stringify() {
        return addStringified(new StringBuilder(), this).toString();
    }

    /**
     * Unpack a string created by {@link #stringify}.
     *
     * @throws IllegalArgumentException if it's an invalid string.
     */
    public static AccountWithDataSet unstringify(String s) {
        final String[] array = STRINGIFY_SEPARATOR_PAT.split(s, 3);
        if (array.length < 3) {
            throw new IllegalArgumentException("Invalid string " + s);
        }
        return new AccountWithDataSet(array[0], array[1],
                TextUtils.isEmpty(array[2]) ? null : array[2]);
    }

    /**
     * Pack a list of {@link AccountWithDataSet} into a string.
     */
    public static String stringifyList(List<AccountWithDataSet> accounts) {
        final StringBuilder sb = new StringBuilder();

        for (AccountWithDataSet account : accounts) {
            if (sb.length() > 0) {
                sb.append(ARRAY_STRINGIFY_SEPARATOR);
            }
            addStringified(sb, account);
        }

        return sb.toString();
    }

    /**
     * Unpack a list of {@link AccountWithDataSet} into a string.
     *
     * @throws IllegalArgumentException if it's an invalid string.
     */
    public static List<AccountWithDataSet> unstringifyList(String s) {
        final ArrayList<AccountWithDataSet> ret = Lists.newArrayList();
        if (TextUtils.isEmpty(s)) {
            return ret;
        }

        final String[] array = ARRAY_STRINGIFY_SEPARATOR_PAT.split(s);

        for (int i = 0; i < array.length; i++) {
            ret.add(unstringify(array[i]));
        }

        return ret;
    }

    public static AccountWithDataSet getDefaultOrBestFallback(ContactsPreferences preferences,
            AccountTypeManager accountTypeManager) {
        if (preferences.isDefaultAccountSet()) {
            final AccountWithDataSet account = preferences.getDefaultAccount();
            if (accountTypeManager.contains(account, true)) {
                return account;
            }
        }
        final List<AccountWithDataSet> accounts = accountTypeManager
                .getAccounts(/* writableOnly */ true);

        if (accounts.isEmpty()) {
            return AccountWithDataSet.getNullAccount();
        }

        // Return the first google account
        for (AccountWithDataSet account : accounts) {
            if (GoogleAccountType.ACCOUNT_TYPE.equals(account) && account.dataSet == null) {
                return account;
            }
        }
        // Arbitrarily return the first writable account
        return accounts.get(0);
    }
}
