/*
 * Copyright (C) 2012 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;

import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.provider.ContactsContract;

import com.android.contacts.common.test.NeededForTesting;
import com.google.common.collect.Sets;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Type of {@link android.content.ContentValues} that maintains both an original state and a
 * modified version of that state. This allows us to build insert, update,
 * or delete operations based on a "before" {@link Entity} snapshot.
 */
public class ValuesDelta implements Parcelable {
    protected ContentValues mBefore;
    protected ContentValues mAfter;
    protected String mIdColumn = BaseColumns._ID;
    private boolean mFromTemplate;

    /**
     * Next value to assign to {@link #mIdColumn} when building an insert
     * operation through {@link #fromAfter(android.content.ContentValues)}. This is used so
     * we can concretely reference this {@link ValuesDelta} before it has
     * been persisted.
     */
    protected static int sNextInsertId = -1;

    protected ValuesDelta() {
    }

    /**
     * Create {@link ValuesDelta}, using the given object as the
     * "before" state, usually from an {@link Entity}.
     */
    public static ValuesDelta fromBefore(ContentValues before) {
        final ValuesDelta entry = new ValuesDelta();
        entry.mBefore = before;
        entry.mAfter = new ContentValues();
        return entry;
    }

    /**
     * Create {@link ValuesDelta}, using the given object as the "after"
     * state, usually when we are inserting a row instead of updating.
     */
    public static ValuesDelta fromAfter(ContentValues after) {
        final ValuesDelta entry = new ValuesDelta();
        entry.mBefore = null;
        entry.mAfter = after;

        // Assign temporary id which is dropped before insert.
        entry.mAfter.put(entry.mIdColumn, sNextInsertId--);
        return entry;
    }

    @NeededForTesting
    public ContentValues getAfter() {
        return mAfter;
    }

    public boolean containsKey(String key) {
        return ((mAfter != null && mAfter.containsKey(key)) ||
                (mBefore != null && mBefore.containsKey(key)));
    }

    public String getAsString(String key) {
        if (mAfter != null && mAfter.containsKey(key)) {
            return mAfter.getAsString(key);
        } else if (mBefore != null && mBefore.containsKey(key)) {
            return mBefore.getAsString(key);
        } else {
            return null;
        }
    }

    public byte[] getAsByteArray(String key) {
        if (mAfter != null && mAfter.containsKey(key)) {
            return mAfter.getAsByteArray(key);
        } else if (mBefore != null && mBefore.containsKey(key)) {
            return mBefore.getAsByteArray(key);
        } else {
            return null;
        }
    }

    public Long getAsLong(String key) {
        if (mAfter != null && mAfter.containsKey(key)) {
            return mAfter.getAsLong(key);
        } else if (mBefore != null && mBefore.containsKey(key)) {
            return mBefore.getAsLong(key);
        } else {
            return null;
        }
    }

    public Integer getAsInteger(String key) {
        return getAsInteger(key, null);
    }

    public Integer getAsInteger(String key, Integer defaultValue) {
        if (mAfter != null && mAfter.containsKey(key)) {
            return mAfter.getAsInteger(key);
        } else if (mBefore != null && mBefore.containsKey(key)) {
            return mBefore.getAsInteger(key);
        } else {
            return defaultValue;
        }
    }

    public boolean isChanged(String key) {
        if (mAfter == null || !mAfter.containsKey(key)) {
            return false;
        }

        Object newValue = mAfter.get(key);
        Object oldValue = mBefore.get(key);

        if (oldValue == null) {
            return newValue != null;
        }

        return !oldValue.equals(newValue);
    }

    public String getMimetype() {
        return getAsString(ContactsContract.Data.MIMETYPE);
    }

    public Long getId() {
        return getAsLong(mIdColumn);
    }

    public void setIdColumn(String idColumn) {
        mIdColumn = idColumn;
    }

    public boolean isPrimary() {
        final Long isPrimary = getAsLong(ContactsContract.Data.IS_PRIMARY);
        return isPrimary == null ? false : isPrimary != 0;
    }

    public void setFromTemplate(boolean isFromTemplate) {
        mFromTemplate = isFromTemplate;
    }

    public boolean isFromTemplate() {
        return mFromTemplate;
    }

    public boolean isSuperPrimary() {
        final Long isSuperPrimary = getAsLong(ContactsContract.Data.IS_SUPER_PRIMARY);
        return isSuperPrimary == null ? false : isSuperPrimary != 0;
    }

    public boolean beforeExists() {
        return (mBefore != null && mBefore.containsKey(mIdColumn));
    }

    /**
     * When "after" is present, then visible
     */
    public boolean isVisible() {
        return (mAfter != null);
    }

    /**
     * When "after" is wiped, action is "delete"
     */
    public boolean isDelete() {
        return beforeExists() && (mAfter == null);
    }

    /**
     * When no "before" or "after", is transient
     */
    public boolean isTransient() {
        return (mBefore == null) && (mAfter == null);
    }

    /**
     * When "after" has some changes, action is "update"
     */
    public boolean isUpdate() {
        if (!beforeExists() || mAfter == null || mAfter.size() == 0) {
            return false;
        }
        for (String key : mAfter.keySet()) {
            Object newValue = mAfter.get(key);
            Object oldValue = mBefore.get(key);
            if (oldValue == null) {
                if (newValue != null) {
                    return true;
                }
            } else if (!oldValue.equals(newValue)) {
                return true;
            }
        }
        return false;
    }

    /**
     * When "after" has no changes, action is no-op
     */
    public boolean isNoop() {
        return beforeExists() && (mAfter != null && mAfter.size() == 0);
    }

    /**
     * When no "before" id, and has "after", action is "insert"
     */
    public boolean isInsert() {
        return !beforeExists() && (mAfter != null);
    }

    public void markDeleted() {
        mAfter = null;
    }

    /**
     * Ensure that our internal structure is ready for storing updates.
     */
    private void ensureUpdate() {
        if (mAfter == null) {
            mAfter = new ContentValues();
        }
    }

    public void put(String key, String value) {
        ensureUpdate();
        mAfter.put(key, value);
    }

    public void put(String key, byte[] value) {
        ensureUpdate();
        mAfter.put(key, value);
    }

    public void put(String key, int value) {
        ensureUpdate();
        mAfter.put(key, value);
    }

    public void put(String key, long value) {
        ensureUpdate();
        mAfter.put(key, value);
    }

    public void putNull(String key) {
        ensureUpdate();
        mAfter.putNull(key);
    }

    public void copyStringFrom(ValuesDelta from, String key) {
        ensureUpdate();
        put(key, from.getAsString(key));
    }

    /**
     * Return set of all keys defined through this object.
     */
    public Set<String> keySet() {
        final HashSet<String> keys = Sets.newHashSet();

        if (mBefore != null) {
            for (Map.Entry<String, Object> entry : mBefore.valueSet()) {
                keys.add(entry.getKey());
            }
        }

        if (mAfter != null) {
            for (Map.Entry<String, Object> entry : mAfter.valueSet()) {
                keys.add(entry.getKey());
            }
        }

        return keys;
    }

    /**
     * Return complete set of "before" and "after" values mixed together,
     * giving full state regardless of edits.
     */
    public ContentValues getCompleteValues() {
        final ContentValues values = new ContentValues();
        if (mBefore != null) {
            values.putAll(mBefore);
        }
        if (mAfter != null) {
            values.putAll(mAfter);
        }
        if (values.containsKey(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID)) {
            // Clear to avoid double-definitions, and prefer rows
            values.remove(ContactsContract.CommonDataKinds.GroupMembership.GROUP_SOURCE_ID);
        }

        return values;
    }

    /**
     * Merge the "after" values from the given {@link ValuesDelta},
     * discarding any existing "after" state. This is typically used when
     * re-parenting changes onto an updated {@link Entity}.
     */
    public static ValuesDelta mergeAfter(ValuesDelta local, ValuesDelta remote) {
        // Bail early if trying to merge delete with missing local
        if (local == null && (remote.isDelete() || remote.isTransient())) return null;

        // Create local version if none exists yet
        if (local == null) local = new ValuesDelta();

        if (!local.beforeExists()) {
            // Any "before" record is missing, so take all values as "insert"
            local.mAfter = remote.getCompleteValues();
        } else {
            // Existing "update" with only "after" values
            local.mAfter = remote.mAfter;
        }

        return local;
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof ValuesDelta) {
            // Only exactly equal with both are identical subsets
            final ValuesDelta other = (ValuesDelta)object;
            return this.subsetEquals(other) && other.subsetEquals(this);
        }
        return false;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        toString(builder);
        return builder.toString();
    }

    /**
     * Helper for building string representation, leveraging the given
     * {@link StringBuilder} to minimize allocations.
     */
    public void toString(StringBuilder builder) {
        builder.append("{ ");
        builder.append("IdColumn=");
        builder.append(mIdColumn);
        builder.append(", FromTemplate=");
        builder.append(mFromTemplate);
        builder.append(", ");
        for (String key : this.keySet()) {
            builder.append(key);
            builder.append("=");
            builder.append(this.getAsString(key));
            builder.append(", ");
        }
        builder.append("}");
    }

    /**
     * Check if the given {@link ValuesDelta} is both a subset of this
     * object, and any defined keys have equal values.
     */
    public boolean subsetEquals(ValuesDelta other) {
        for (String key : this.keySet()) {
            final String ourValue = this.getAsString(key);
            final String theirValue = other.getAsString(key);
            if (ourValue == null) {
                // If they have value when we're null, no match
                if (theirValue != null) return false;
            } else {
                // If both values defined and aren't equal, no match
                if (!ourValue.equals(theirValue)) return false;
            }
        }
        // All values compared and matched
        return true;
    }

    /**
     * Build a {@link android.content.ContentProviderOperation} that will transform our
     * "before" state into our "after" state, using insert, update, or
     * delete as needed.
     */
    public ContentProviderOperation.Builder buildDiff(Uri targetUri) {
        ContentProviderOperation.Builder builder = null;
        if (isInsert()) {
            // Changed values are "insert" back-referenced to Contact
            mAfter.remove(mIdColumn);
            builder = ContentProviderOperation.newInsert(targetUri);
            builder.withValues(mAfter);
        } else if (isDelete()) {
            // When marked for deletion and "before" exists, then "delete"
            builder = ContentProviderOperation.newDelete(targetUri);
            builder.withSelection(mIdColumn + "=" + getId(), null);
        } else if (isUpdate()) {
            // When has changes and "before" exists, then "update"
            builder = ContentProviderOperation.newUpdate(targetUri);
            builder.withSelection(mIdColumn + "=" + getId(), null);
            builder.withValues(mAfter);
        }
        return builder;
    }

    /** {@inheritDoc} */
    public int describeContents() {
        // Nothing special about this parcel
        return 0;
    }

    /** {@inheritDoc} */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mBefore, flags);
        dest.writeParcelable(mAfter, flags);
        dest.writeString(mIdColumn);
    }

    public void readFromParcel(Parcel source) {
        final ClassLoader loader = getClass().getClassLoader();
        mBefore = source.<ContentValues> readParcelable(loader);
        mAfter = source.<ContentValues> readParcelable(loader);
        mIdColumn = source.readString();
    }

    public static final Creator<ValuesDelta> CREATOR = new Creator<ValuesDelta>() {
        public ValuesDelta createFromParcel(Parcel in) {
            final ValuesDelta values = new ValuesDelta();
            values.readFromParcel(in);
            return values;
        }

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

    public void setGroupRowId(long groupId) {
        put(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, groupId);
    }

    public Long getGroupRowId() {
        return getAsLong(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID);
    }

    public void setPhoto(byte[] value) {
        put(ContactsContract.CommonDataKinds.Photo.PHOTO, value);
    }

    public byte[] getPhoto() {
        return getAsByteArray(ContactsContract.CommonDataKinds.Photo.PHOTO);
    }

    public void setSuperPrimary(boolean val) {
        if (val) {
            put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
        } else {
            put(ContactsContract.Data.IS_SUPER_PRIMARY, 0);
        }
    }

    public void setPhoneticFamilyName(String value) {
        put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME, value);
    }

    public void setPhoneticMiddleName(String value) {
        put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_MIDDLE_NAME, value);
    }

    public void setPhoneticGivenName(String value) {
        put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_GIVEN_NAME, value);
    }

    public String getPhoneticFamilyName() {
        return getAsString(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME);
    }

    public String getPhoneticMiddleName() {
        return getAsString(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_MIDDLE_NAME);
    }

    public String getPhoneticGivenName() {
        return getAsString(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_GIVEN_NAME);
    }

    public String getDisplayName() {
        return getAsString(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
    }

    public void setDisplayName(String name) {
        if (name == null) {
            putNull(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
        } else {
            put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
        }
    }

    public void copyStructuredNameFieldsFrom(ValuesDelta name) {
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);

        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.PREFIX);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.SUFFIX);

        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.PHONETIC_GIVEN_NAME);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.PHONETIC_MIDDLE_NAME);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME);

        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.FULL_NAME_STYLE);
        copyStringFrom(name, ContactsContract.CommonDataKinds.StructuredName.PHONETIC_NAME_STYLE);
    }

    public String getPhoneNumber() {
        return getAsString(ContactsContract.CommonDataKinds.Phone.NUMBER);
    }

    public String getPhoneNormalizedNumber() {
        return getAsString(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER);
    }

    public boolean phoneHasType() {
        return containsKey(ContactsContract.CommonDataKinds.Phone.TYPE);
    }

    public int getPhoneType() {
        return getAsInteger(ContactsContract.CommonDataKinds.Phone.TYPE);
    }

    public String getPhoneLabel() {
        return getAsString(ContactsContract.CommonDataKinds.Phone.LABEL);
    }

    public String getEmailData() {
        return getAsString(ContactsContract.CommonDataKinds.Email.DATA);
    }

    public boolean emailHasType() {
        return containsKey(ContactsContract.CommonDataKinds.Email.TYPE);
    }

    public int getEmailType() {
        return getAsInteger(ContactsContract.CommonDataKinds.Email.TYPE);
    }

    public String getEmailLabel() {
        return getAsString(ContactsContract.CommonDataKinds.Email.LABEL);
    }
}
