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

import android.annotation.UnsupportedAppUsage;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Represents a single operation to be performed as part of a batch of operations.
 *
 * @see ContentProvider#applyBatch(ArrayList)
 */
public class ContentProviderOperation implements Parcelable {
    /** @hide exposed for unit tests */
    @UnsupportedAppUsage
    public final static int TYPE_INSERT = 1;
    /** @hide exposed for unit tests */
    @UnsupportedAppUsage
    public final static int TYPE_UPDATE = 2;
    /** @hide exposed for unit tests */
    @UnsupportedAppUsage
    public final static int TYPE_DELETE = 3;
    /** @hide exposed for unit tests */
    public final static int TYPE_ASSERT = 4;

    @UnsupportedAppUsage
    private final int mType;
    @UnsupportedAppUsage
    private final Uri mUri;
    @UnsupportedAppUsage
    private final String mSelection;
    private final String[] mSelectionArgs;
    private final ContentValues mValues;
    private final Integer mExpectedCount;
    private final ContentValues mValuesBackReferences;
    private final Map<Integer, Integer> mSelectionArgsBackReferences;
    private final boolean mYieldAllowed;
    private final boolean mFailureAllowed;

    private final static String TAG = "ContentProviderOperation";

    /**
     * Creates a {@link ContentProviderOperation} by copying the contents of a
     * {@link Builder}.
     */
    private ContentProviderOperation(Builder builder) {
        mType = builder.mType;
        mUri = builder.mUri;
        mValues = builder.mValues;
        mSelection = builder.mSelection;
        mSelectionArgs = builder.mSelectionArgs;
        mExpectedCount = builder.mExpectedCount;
        mSelectionArgsBackReferences = builder.mSelectionArgsBackReferences;
        mValuesBackReferences = builder.mValuesBackReferences;
        mYieldAllowed = builder.mYieldAllowed;
        mFailureAllowed = builder.mFailureAllowed;
    }

    private ContentProviderOperation(Parcel source) {
        mType = source.readInt();
        mUri = Uri.CREATOR.createFromParcel(source);
        mValues = source.readInt() != 0 ? ContentValues.CREATOR.createFromParcel(source) : null;
        mSelection = source.readInt() != 0 ? source.readString() : null;
        mSelectionArgs = source.readInt() != 0 ? source.readStringArray() : null;
        mExpectedCount = source.readInt() != 0 ? source.readInt() : null;
        mValuesBackReferences = source.readInt() != 0
                ? ContentValues.CREATOR.createFromParcel(source)
                : null;
        mSelectionArgsBackReferences = source.readInt() != 0
                ? new HashMap<Integer, Integer>()
                : null;
        if (mSelectionArgsBackReferences != null) {
            final int count = source.readInt();
            for (int i = 0; i < count; i++) {
                mSelectionArgsBackReferences.put(source.readInt(), source.readInt());
            }
        }
        mYieldAllowed = source.readInt() != 0;
        mFailureAllowed = source.readInt() != 0;
    }

    /** @hide */
    public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) {
        mType = cpo.mType;
        mUri = withUri;
        mValues = cpo.mValues;
        mSelection = cpo.mSelection;
        mSelectionArgs = cpo.mSelectionArgs;
        mExpectedCount = cpo.mExpectedCount;
        mSelectionArgsBackReferences = cpo.mSelectionArgsBackReferences;
        mValuesBackReferences = cpo.mValuesBackReferences;
        mYieldAllowed = cpo.mYieldAllowed;
        mFailureAllowed = cpo.mFailureAllowed;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mType);
        Uri.writeToParcel(dest, mUri);
        if (mValues != null) {
            dest.writeInt(1);
            mValues.writeToParcel(dest, 0);
        } else {
            dest.writeInt(0);
        }
        if (mSelection != null) {
            dest.writeInt(1);
            dest.writeString(mSelection);
        } else {
            dest.writeInt(0);
        }
        if (mSelectionArgs != null) {
            dest.writeInt(1);
            dest.writeStringArray(mSelectionArgs);
        } else {
            dest.writeInt(0);
        }
        if (mExpectedCount != null) {
            dest.writeInt(1);
            dest.writeInt(mExpectedCount);
        } else {
            dest.writeInt(0);
        }
        if (mValuesBackReferences != null) {
            dest.writeInt(1);
            mValuesBackReferences.writeToParcel(dest, 0);
        } else {
            dest.writeInt(0);
        }
        if (mSelectionArgsBackReferences != null) {
            dest.writeInt(1);
            dest.writeInt(mSelectionArgsBackReferences.size());
            for (Map.Entry<Integer, Integer> entry : mSelectionArgsBackReferences.entrySet()) {
                dest.writeInt(entry.getKey());
                dest.writeInt(entry.getValue());
            }
        } else {
            dest.writeInt(0);
        }
        dest.writeInt(mYieldAllowed ? 1 : 0);
        dest.writeInt(mFailureAllowed ? 1 : 0);
    }

    /**
     * Create a {@link Builder} suitable for building an insert {@link ContentProviderOperation}.
     * @param uri The {@link Uri} that is the target of the insert.
     * @return a {@link Builder}
     */
    public static Builder newInsert(Uri uri) {
        return new Builder(TYPE_INSERT, uri);
    }

    /**
     * Create a {@link Builder} suitable for building an update {@link ContentProviderOperation}.
     * @param uri The {@link Uri} that is the target of the update.
     * @return a {@link Builder}
     */
    public static Builder newUpdate(Uri uri) {
        return new Builder(TYPE_UPDATE, uri);
    }

    /**
     * Create a {@link Builder} suitable for building a delete {@link ContentProviderOperation}.
     * @param uri The {@link Uri} that is the target of the delete.
     * @return a {@link Builder}
     */
    public static Builder newDelete(Uri uri) {
        return new Builder(TYPE_DELETE, uri);
    }

    /**
     * Create a {@link Builder} suitable for building a
     * {@link ContentProviderOperation} to assert a set of values as provided
     * through {@link Builder#withValues(ContentValues)}.
     */
    public static Builder newAssertQuery(Uri uri) {
        return new Builder(TYPE_ASSERT, uri);
    }

    /**
     * Gets the Uri for the target of the operation.
     */
    public Uri getUri() {
        return mUri;
    }

    /**
     * Returns true if the operation allows yielding the database to other transactions
     * if the database is contended.
     *
     * @see android.database.sqlite.SQLiteDatabase#yieldIfContendedSafely()
     */
    public boolean isYieldAllowed() {
        return mYieldAllowed;
    }

    /** {@hide} */
    public boolean isFailureAllowed() {
        return mFailureAllowed;
    }

    /** @hide exposed for unit tests */
    @UnsupportedAppUsage
    public int getType() {
        return mType;
    }

    /**
     * Returns true if the operation represents an insertion.
     *
     * @see #newInsert
     */
    public boolean isInsert() {
        return mType == TYPE_INSERT;
    }

    /**
     * Returns true if the operation represents a deletion.
     *
     * @see #newDelete
     */
    public boolean isDelete() {
        return mType == TYPE_DELETE;
    }

    /**
     * Returns true if the operation represents an update.
     *
     * @see #newUpdate
     */
    public boolean isUpdate() {
        return mType == TYPE_UPDATE;
    }

    /**
     * Returns true if the operation represents an assert query.
     *
     * @see #newAssertQuery
     */
    public boolean isAssertQuery() {
        return mType == TYPE_ASSERT;
    }

    /**
     * Returns true if the operation represents an insertion, deletion, or update.
     *
     * @see #isInsert
     * @see #isDelete
     * @see #isUpdate
     */
    public boolean isWriteOperation() {
        return mType == TYPE_DELETE || mType == TYPE_INSERT || mType == TYPE_UPDATE;
    }

    /**
     * Returns true if the operation represents an assert query.
     *
     * @see #isAssertQuery
     */
    public boolean isReadOperation() {
        return mType == TYPE_ASSERT;
    }

    /**
     * Applies this operation using the given provider. The backRefs array is used to resolve any
     * back references that were requested using
     * {@link Builder#withValueBackReferences(ContentValues)} and
     * {@link Builder#withSelectionBackReference}.
     * @param provider the {@link ContentProvider} on which this batch is applied
     * @param backRefs a {@link ContentProviderResult} array that will be consulted
     * to resolve any requested back references.
     * @param numBackRefs the number of valid results on the backRefs array.
     * @return a {@link ContentProviderResult} that contains either the {@link Uri} of the inserted
     * row if this was an insert otherwise the number of rows affected.
     * @throws OperationApplicationException thrown if either the insert fails or
     * if the number of rows affected didn't match the expected count
     */
    public ContentProviderResult apply(ContentProvider provider, ContentProviderResult[] backRefs,
            int numBackRefs) throws OperationApplicationException {
        if (mFailureAllowed) {
            try {
                return applyInternal(provider, backRefs, numBackRefs);
            } catch (Exception e) {
                return new ContentProviderResult(e.getMessage());
            }
        } else {
            return applyInternal(provider, backRefs, numBackRefs);
        }
    }

    private ContentProviderResult applyInternal(ContentProvider provider,
            ContentProviderResult[] backRefs, int numBackRefs)
            throws OperationApplicationException {
        ContentValues values = resolveValueBackReferences(backRefs, numBackRefs);
        String[] selectionArgs =
                resolveSelectionArgsBackReferences(backRefs, numBackRefs);

        if (mType == TYPE_INSERT) {
            final Uri newUri = provider.insert(mUri, values);
            if (newUri != null) {
                return new ContentProviderResult(newUri);
            } else {
                throw new OperationApplicationException(
                        "Insert into " + mUri + " returned no result");
            }
        }

        final int numRows;
        if (mType == TYPE_DELETE) {
            numRows = provider.delete(mUri, mSelection, selectionArgs);
        } else if (mType == TYPE_UPDATE) {
            numRows = provider.update(mUri, values, mSelection, selectionArgs);
        } else if (mType == TYPE_ASSERT) {
            // Assert that all rows match expected values
            String[] projection =  null;
            if (values != null) {
                // Build projection map from expected values
                final ArrayList<String> projectionList = new ArrayList<String>();
                for (Map.Entry<String, Object> entry : values.valueSet()) {
                    projectionList.add(entry.getKey());
                }
                projection = projectionList.toArray(new String[projectionList.size()]);
            }
            final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null);
            try {
                numRows = cursor.getCount();
                if (projection != null) {
                    while (cursor.moveToNext()) {
                        for (int i = 0; i < projection.length; i++) {
                            final String cursorValue = cursor.getString(i);
                            final String expectedValue = values.getAsString(projection[i]);
                            if (!TextUtils.equals(cursorValue, expectedValue)) {
                                // Throw exception when expected values don't match
                                throw new OperationApplicationException("Found value " + cursorValue
                                        + " when expected " + expectedValue + " for column "
                                        + projection[i]);
                            }
                        }
                    }
                }
            } finally {
                cursor.close();
            }
        } else {
            throw new IllegalStateException("bad type, " + mType);
        }

        if (mExpectedCount != null && mExpectedCount != numRows) {
            throw new OperationApplicationException(
                    "Expected " + mExpectedCount + " rows but actual " + numRows);
        }

        return new ContentProviderResult(numRows);
    }

    /**
     * The ContentValues back references are represented as a ContentValues object where the
     * key refers to a column and the value is an index of the back reference whose
     * valued should be associated with the column.
     * <p>
     * This is intended to be a private method but it is exposed for
     * unit testing purposes
     * @param backRefs an array of previous results
     * @param numBackRefs the number of valid previous results in backRefs
     * @return the ContentValues that should be used in this operation application after
     * expansion of back references. This can be called if either mValues or mValuesBackReferences
     * is null
     */
    public ContentValues resolveValueBackReferences(
            ContentProviderResult[] backRefs, int numBackRefs) {
        if (mValuesBackReferences == null) {
            return mValues;
        }
        final ContentValues values;
        if (mValues == null) {
            values = new ContentValues();
        } else {
            values = new ContentValues(mValues);
        }
        for (Map.Entry<String, Object> entry : mValuesBackReferences.valueSet()) {
            String key = entry.getKey();
            Integer backRefIndex = mValuesBackReferences.getAsInteger(key);
            if (backRefIndex == null) {
                Log.e(TAG, this.toString());
                throw new IllegalArgumentException("values backref " + key + " is not an integer");
            }
            values.put(key, backRefToValue(backRefs, numBackRefs, backRefIndex));
        }
        return values;
    }

    /**
     * The Selection Arguments back references are represented as a Map of Integer->Integer where
     * the key is an index into the selection argument array (see {@link Builder#withSelection})
     * and the value is the index of the previous result that should be used for that selection
     * argument array slot.
     * <p>
     * This is intended to be a private method but it is exposed for
     * unit testing purposes
     * @param backRefs an array of previous results
     * @param numBackRefs the number of valid previous results in backRefs
     * @return the ContentValues that should be used in this operation application after
     * expansion of back references. This can be called if either mValues or mValuesBackReferences
     * is null
     */
    public String[] resolveSelectionArgsBackReferences(
            ContentProviderResult[] backRefs, int numBackRefs) {
        if (mSelectionArgsBackReferences == null) {
            return mSelectionArgs;
        }
        String[] newArgs = new String[mSelectionArgs.length];
        System.arraycopy(mSelectionArgs, 0, newArgs, 0, mSelectionArgs.length);
        for (Map.Entry<Integer, Integer> selectionArgBackRef
                : mSelectionArgsBackReferences.entrySet()) {
            final Integer selectionArgIndex = selectionArgBackRef.getKey();
            final int backRefIndex = selectionArgBackRef.getValue();
            newArgs[selectionArgIndex] =
                    String.valueOf(backRefToValue(backRefs, numBackRefs, backRefIndex));
        }
        return newArgs;
    }

    @Override
    public String toString() {
        return "mType: " + mType + ", mUri: " + mUri +
                ", mSelection: " + mSelection +
                ", mExpectedCount: " + mExpectedCount +
                ", mYieldAllowed: " + mYieldAllowed +
                ", mValues: " + mValues +
                ", mValuesBackReferences: " + mValuesBackReferences +
                ", mSelectionArgsBackReferences: " + mSelectionArgsBackReferences;
    }

    /**
     * Return the string representation of the requested back reference.
     * @param backRefs an array of results
     * @param numBackRefs the number of items in the backRefs array that are valid
     * @param backRefIndex which backRef to be used
     * @throws ArrayIndexOutOfBoundsException thrown if the backRefIndex is larger than
     * the numBackRefs
     * @return the string representation of the requested back reference.
     */
    private long backRefToValue(ContentProviderResult[] backRefs, int numBackRefs,
            Integer backRefIndex) {
        if (backRefIndex >= numBackRefs) {
            Log.e(TAG, this.toString());
            throw new ArrayIndexOutOfBoundsException("asked for back ref " + backRefIndex
                    + " but there are only " + numBackRefs + " back refs");
        }
        ContentProviderResult backRef = backRefs[backRefIndex];
        long backRefValue;
        if (backRef.uri != null) {
            backRefValue = ContentUris.parseId(backRef.uri);
        } else {
            backRefValue = backRef.count;
        }
        return backRefValue;
    }

    public int describeContents() {
        return 0;
    }

    public static final @android.annotation.NonNull Creator<ContentProviderOperation> CREATOR =
            new Creator<ContentProviderOperation>() {
        public ContentProviderOperation createFromParcel(Parcel source) {
            return new ContentProviderOperation(source);
        }

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

    /**
     * Used to add parameters to a {@link ContentProviderOperation}. The {@link Builder} is
     * first created by calling {@link ContentProviderOperation#newInsert(android.net.Uri)},
     * {@link ContentProviderOperation#newUpdate(android.net.Uri)},
     * {@link ContentProviderOperation#newDelete(android.net.Uri)} or
     * {@link ContentProviderOperation#newAssertQuery(Uri)}. The withXXX methods
     * can then be used to add parameters to the builder. See the specific methods to find for
     * which {@link Builder} type each is allowed. Call {@link #build} to create the
     * {@link ContentProviderOperation} once all the parameters have been supplied.
     */
    public static class Builder {
        private final int mType;
        private final Uri mUri;
        private String mSelection;
        private String[] mSelectionArgs;
        private ContentValues mValues;
        private Integer mExpectedCount;
        private ContentValues mValuesBackReferences;
        private Map<Integer, Integer> mSelectionArgsBackReferences;
        private boolean mYieldAllowed;
        private boolean mFailureAllowed;

        /** Create a {@link Builder} of a given type. The uri must not be null. */
        private Builder(int type, Uri uri) {
            if (uri == null) {
                throw new IllegalArgumentException("uri must not be null");
            }
            mType = type;
            mUri = uri;
        }

        /** Create a ContentProviderOperation from this {@link Builder}. */
        public ContentProviderOperation build() {
            if (mType == TYPE_UPDATE) {
                if ((mValues == null || mValues.isEmpty())
                      && (mValuesBackReferences == null || mValuesBackReferences.isEmpty())) {
                    throw new IllegalArgumentException("Empty values");
                }
            }
            if (mType == TYPE_ASSERT) {
                if ((mValues == null || mValues.isEmpty())
                      && (mValuesBackReferences == null || mValuesBackReferences.isEmpty())
                        && (mExpectedCount == null)) {
                    throw new IllegalArgumentException("Empty values");
                }
            }
            return new ContentProviderOperation(this);
        }

        /**
         * Add a {@link ContentValues} of back references. The key is the name of the column
         * and the value is an integer that is the index of the previous result whose
         * value should be used for the column. The value is added as a {@link String}.
         * A column value from the back references takes precedence over a value specified in
         * {@link #withValues}.
         * This can only be used with builders of type insert, update, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withValueBackReferences(ContentValues backReferences) {
            if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException(
                        "only inserts, updates, and asserts can have value back-references");
            }
            mValuesBackReferences = backReferences;
            return this;
        }

        /**
         * Add a ContentValues back reference.
         * A column value from the back references takes precedence over a value specified in
         * {@link #withValues}.
         * This can only be used with builders of type insert, update, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withValueBackReference(String key, int previousResult) {
            if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException(
                        "only inserts, updates, and asserts can have value back-references");
            }
            if (mValuesBackReferences == null) {
                mValuesBackReferences = new ContentValues();
            }
            mValuesBackReferences.put(key, previousResult);
            return this;
        }

        /**
         * Add a back references as a selection arg. Any value at that index of the selection arg
         * that was specified by {@link #withSelection} will be overwritten.
         * This can only be used with builders of type update, delete, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withSelectionBackReference(int selectionArgIndex, int previousResult) {
            if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException("only updates, deletes, and asserts "
                        + "can have selection back-references");
            }
            if (mSelectionArgsBackReferences == null) {
                mSelectionArgsBackReferences = new HashMap<Integer, Integer>();
            }
            mSelectionArgsBackReferences.put(selectionArgIndex, previousResult);
            return this;
        }

        /**
         * The ContentValues to use. This may be null. These values may be overwritten by
         * the corresponding value specified by {@link #withValueBackReference} or by
         * future calls to {@link #withValues} or {@link #withValue}.
         * This can only be used with builders of type insert, update, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withValues(ContentValues values) {
            if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException(
                        "only inserts, updates, and asserts can have values");
            }
            if (mValues == null) {
                mValues = new ContentValues();
            }
            mValues.putAll(values);
            return this;
        }

        /**
         * A value to insert or update. This value may be overwritten by
         * the corresponding value specified by {@link #withValueBackReference}.
         * This can only be used with builders of type insert, update, or assert.
         * @param key the name of this value
         * @param value the value itself. the type must be acceptable for insertion by
         * {@link ContentValues#put}
         * @return this builder, to allow for chaining.
         */
        public Builder withValue(String key, Object value) {
            if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException("only inserts and updates can have values");
            }
            if (mValues == null) {
                mValues = new ContentValues();
            }
            if (value == null) {
                mValues.putNull(key);
            } else if (value instanceof String) {
                mValues.put(key, (String) value);
            } else if (value instanceof Byte) {
                mValues.put(key, (Byte) value);
            } else if (value instanceof Short) {
                mValues.put(key, (Short) value);
            } else if (value instanceof Integer) {
                mValues.put(key, (Integer) value);
            } else if (value instanceof Long) {
                mValues.put(key, (Long) value);
            } else if (value instanceof Float) {
                mValues.put(key, (Float) value);
            } else if (value instanceof Double) {
                mValues.put(key, (Double) value);
            } else if (value instanceof Boolean) {
                mValues.put(key, (Boolean) value);
            } else if (value instanceof byte[]) {
                mValues.put(key, (byte[]) value);
            } else {
                throw new IllegalArgumentException("bad value type: " + value.getClass().getName());
            }
            return this;
        }

        /**
         * The selection and arguments to use. An occurrence of '?' in the selection will be
         * replaced with the corresponding occurrence of the selection argument. Any of the
         * selection arguments may be overwritten by a selection argument back reference as
         * specified by {@link #withSelectionBackReference}.
         * This can only be used with builders of type update, delete, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withSelection(String selection, String[] selectionArgs) {
            if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException(
                        "only updates, deletes, and asserts can have selections");
            }
            mSelection = selection;
            if (selectionArgs == null) {
                mSelectionArgs = null;
            } else {
                mSelectionArgs = new String[selectionArgs.length];
                System.arraycopy(selectionArgs, 0, mSelectionArgs, 0, selectionArgs.length);
            }
            return this;
        }

        /**
         * If set then if the number of rows affected by this operation does not match
         * this count {@link OperationApplicationException} will be throw.
         * This can only be used with builders of type update, delete, or assert.
         * @return this builder, to allow for chaining.
         */
        public Builder withExpectedCount(int count) {
            if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
                throw new IllegalArgumentException(
                        "only updates, deletes, and asserts can have expected counts");
            }
            mExpectedCount = count;
            return this;
        }

        /**
         * If set to true then the operation allows yielding the database to other transactions
         * if the database is contended.
         * @return this builder, to allow for chaining.
         * @see android.database.sqlite.SQLiteDatabase#yieldIfContendedSafely()
         */
        public Builder withYieldAllowed(boolean yieldAllowed) {
            mYieldAllowed = yieldAllowed;
            return this;
        }

        /** {@hide} */
        public Builder withFailureAllowed(boolean failureAllowed) {
            mFailureAllowed = failureAllowed;
            return this;
        }
    }
}
