/*
 * Copyright (C) 2010 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.test.mocks;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;

import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.support.annotation.Nullable;

import junit.framework.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * A programmable mock content provider.
 */
public class MockContentProvider extends android.test.mock.MockContentProvider {
    private static final String TAG = "MockContentProvider";

    public static class Query {

        private final Uri mUri;
        private UriMatcher mMatcher;

        private String[] mProjection;
        private String[] mDefaultProjection;
        private String mSelection;
        private String[] mSelectionArgs;
        private String mSortOrder;
        private List<Object> mRows = new ArrayList<>();
        private boolean mAnyProjection;
        private boolean mAnySelection;
        private boolean mAnySortOrder;
        private boolean mAnyNumberOfTimes;

        private boolean mExecuted;

        private Query() {
            mUri = null;
        }

        private Query(UriMatcher matcher) {
            mUri = null;
            mMatcher = matcher;
        }

        public Query(Uri uri) {
            mUri = uri;
        }

        @Override
        public String toString() {
            return queryToString(mUri, mProjection, mSelection, mSelectionArgs, mSortOrder);
        }

        public Query withProjection(String... projection) {
            mProjection = projection;
            return this;
        }

        public Query withDefaultProjection(String... projection) {
            mDefaultProjection = projection;
            return this;
        }

        public Query withAnyProjection() {
            mAnyProjection = true;
            return this;
        }

        public Query withSelection(String selection, String... selectionArgs) {
            mSelection = selection;
            mSelectionArgs = selectionArgs;
            return this;
        }

        public Query withAnySelection() {
            mAnySelection = true;
            return this;
        }

        public Query withSortOrder(String sortOrder) {
            mSortOrder = sortOrder;
            return this;
        }

        public Query withAnySortOrder() {
            mAnySortOrder = true;
            return this;
        }

        public Query returnRow(ContentValues values) {
            mRows.add(values);
            return this;
        }

        public Query returnRow(Object... row) {
            mRows.add(row);
            return this;
        }

        public Query returnEmptyCursor() {
            mRows.clear();
            return this;
        }

        public Query anyNumberOfTimes() {
            mAnyNumberOfTimes = true;
            return this;
        }

        public boolean equals(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            if (mUri == null) {
                if (mMatcher != null && mMatcher.match(uri) == UriMatcher.NO_MATCH) {
                    return false;
                }
            } else if (!uri.equals(mUri)) {
                return false;
            }

            if (!mAnyProjection && !Arrays.equals(projection, mProjection)) {
                return false;
            }

            if (!mAnySelection && !Objects.equals(selection, mSelection)) {
                return false;
            }

            if (!mAnySelection && !Arrays.equals(selectionArgs, mSelectionArgs)) {
                return false;
            }

            if (!mAnySortOrder && !Objects.equals(sortOrder, mSortOrder)) {
                return false;
            }

            return true;
        }

        public Cursor getResult(String[] projection) {
            String[] columnNames;
            if (mAnyProjection) {
                columnNames = projection != null ? projection : mDefaultProjection;
            } else {
                columnNames = mProjection != null ? mProjection : mDefaultProjection;
            }

            MatrixCursor cursor = new MatrixCursor(columnNames);
            for (Object row : mRows) {
                if (row instanceof Object[]) {
                    cursor.addRow((Object[]) row);
                } else {
                    ContentValues values = (ContentValues) row;
                    Object[] columns = new Object[columnNames.length];
                    for (int i = 0; i < columnNames.length; i++) {
                        columns[i] = values.get(columnNames[i]);
                    }
                    cursor.addRow(columns);
                }
            }
            return cursor;
        }

        public static Query forAnyUri() {
            return new Query();
        }

        public static Query forUrisMatching(UriMatcher matcher) {
            return new Query(matcher);
        }

        public static Query forUrisMatching(String authority, String... paths) {
            final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
            for (int i = 0; i < paths.length; i++) {
                matcher.addURI(authority, paths[i], i);
            }
            return new Query(matcher);
        }

    }

    public static class TypeQuery {
        private final Uri mUri;
        private final String mType;

        public TypeQuery(Uri uri, String type) {
            mUri = uri;
            mType = type;
        }

        public Uri getUri() {
            return mUri;
        }

        public String getType() {
            return mType;
        }

        @Override
        public String toString() {
            return mUri + " --> " + mType;
        }

        public boolean equals(Uri uri) {
            return getUri().equals(uri);
        }
    }

    public static class Insert {
        private final Uri mUri;
        private final ContentValues mContentValues;
        private final Uri mResultUri;
        private boolean mAnyNumberOfTimes;
        private boolean mIsExecuted;

        /**
         * Creates a new Insert to expect.
         *
         * @param uri the uri of the insertion request.
         * @param contentValues the ContentValues to insert.
         * @param resultUri the {@link Uri} for the newly inserted item.
         * @throws NullPointerException if any parameter is {@code null}.
         */
        public Insert(Uri uri, ContentValues contentValues, Uri resultUri) {
            mUri = Preconditions.checkNotNull(uri);
            mContentValues = Preconditions.checkNotNull(contentValues);
            mResultUri = Preconditions.checkNotNull(resultUri);
        }

        /**
         * Causes this insert expectation to be useable for mutliple calls to insert, rather than
         * just one.
         *
         * @return this
         */
        public Insert anyNumberOfTimes() {
            mAnyNumberOfTimes = true;
            return this;
        }

        private boolean equals(Uri uri, ContentValues contentValues) {
            return mUri.equals(uri) && mContentValues.equals(contentValues);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Insert insert = (Insert) o;
            return mAnyNumberOfTimes == insert.mAnyNumberOfTimes &&
                    mIsExecuted == insert.mIsExecuted &&
                    Objects.equals(mUri, insert.mUri) &&
                    Objects.equals(mContentValues, insert.mContentValues) &&
                    Objects.equals(mResultUri, insert.mResultUri);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mUri, mContentValues, mResultUri, mAnyNumberOfTimes, mIsExecuted);
        }

        @Override
        public String toString() {
            return "Insert{" +
                    "mUri=" + mUri +
                    ", mContentValues=" + mContentValues +
                    ", mResultUri=" + mResultUri +
                    ", mAnyNumberOfTimes=" + mAnyNumberOfTimes +
                    ", mIsExecuted=" + mIsExecuted +
                    '}';
        }
    }

    public static class Delete {
        private final Uri mUri;

        private boolean mAnyNumberOfTimes;
        private boolean mAnySelection;
        @Nullable private String mSelection;
        @Nullable private String[] mSelectionArgs;
        private boolean mIsExecuted;
        private int mRowsAffected;

        /**
         * Creates a new Delete to expect.
         * @param uri the uri of the delete request.
         * @throws NullPointerException if uri is {@code null}.
         */
        public Delete(Uri uri) {
            mUri = Preconditions.checkNotNull(uri);
        }

        /**
         * Sets the given information as expected selection arguments.
         *
         * @param selection The selection to expect.
         * @param selectionArgs The selection args to expect.
         * @return this.
         */
        public Delete withSelection(String selection, @Nullable String[] selectionArgs) {
            mSelection = Preconditions.checkNotNull(selection);
            mSelectionArgs = selectionArgs;
            mAnySelection = false;
            return this;
        }

        /**
         * Sets this delete to expect any selection arguments.
         *
         * @return this.
         */
        public Delete withAnySelection() {
            mAnySelection = true;
            return this;
        }

        /**
         * Sets this delete to return the given number of rows affected.
         *
         * @param rowsAffected The value to return when this expected delete is executed.
         * @return this.
         */
        public Delete returnRowsAffected(int rowsAffected) {
            mRowsAffected = rowsAffected;
            return this;
        }

        /**
         * Causes this delete expectation to be useable for multiple calls to delete, rather than
         * just one.
         *
         * @return this.
         */
        public Delete anyNumberOfTimes() {
            mAnyNumberOfTimes = true;
            return this;
        }

        private boolean equals(Uri uri, String selection, String[] selectionArgs) {
            return mUri.equals(uri) && Objects.equals(mSelection, selection)
                    && Arrays.equals(mSelectionArgs, selectionArgs);
        }
    }

    public static class Update {
        private final Uri mUri;
        private final ContentValues mContentValues;
        @Nullable private String mSelection;
        @Nullable private String[] mSelectionArgs;
        private boolean mAnyNumberOfTimes;
        private boolean mIsExecuted;
        private int mRowsAffected;

        /**
         * Creates a new Update to expect.
         *
         * @param uri the uri of the update request.
         * @param contentValues the ContentValues to update.
         *
         * @throws NullPointerException if any parameter is {@code null}.
         */
        public Update(Uri uri,
                      ContentValues contentValues,
                      @Nullable String selection,
                      @Nullable String[] selectionArgs) {
            mUri = Preconditions.checkNotNull(uri);
            mContentValues = Preconditions.checkNotNull(contentValues);
            mSelection = selection;
            mSelectionArgs = selectionArgs;
        }

        /**
         * Causes this update expectation to be useable for mutliple calls to update, rather than
         * just one.
         *
         * @return this
         */
        public Update anyNumberOfTimes() {
            mAnyNumberOfTimes = true;
            return this;
        }

        /**
         * Sets this update to return the given number of rows affected.
         *
         * @param rowsAffected The value to return when this expected update is executed.
         * @return this.
         */
        public Update returnRowsAffected(int rowsAffected) {
            mRowsAffected = rowsAffected;
            return this;
        }

        private boolean equals(Uri uri,
                               ContentValues contentValues,
                               @Nullable String selection,
                               @Nullable String[] selectionArgs) {
            return mUri.equals(uri) && mContentValues.equals(contentValues) &&
                    Objects.equals(mSelection, selection) &&
                    Objects.equals(mSelectionArgs, selectionArgs);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Update update = (Update) o;
            return mAnyNumberOfTimes == update.mAnyNumberOfTimes &&
                    mIsExecuted == update.mIsExecuted &&
                    Objects.equals(mUri, update.mUri) &&
                    Objects.equals(mContentValues, update.mContentValues) &&
                    Objects.equals(mSelection, update.mSelection) &&
                    Objects.equals(mSelectionArgs, update.mSelectionArgs);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mUri, mContentValues, mAnyNumberOfTimes, mIsExecuted, mSelection,
                    mSelectionArgs);
        }

        @Override
        public String toString() {
            return "Update{" +
                    "mUri=" + mUri +
                    ", mContentValues=" + mContentValues +
                    ", mAnyNumberOfTimes=" + mAnyNumberOfTimes +
                    ", mIsExecuted=" + mIsExecuted +
                    ", mSelection=" + mSelection +
                    ", mSelectionArgs=" + mSelectionArgs +
                    '}';
        }
    }

    private List<Query> mExpectedQueries = new ArrayList<>();
    private Map<Uri, String> mExpectedTypeQueries = Maps.newHashMap();
    private List<Insert> mExpectedInserts = new ArrayList<>();
    private List<Delete> mExpectedDeletes = new ArrayList<>();
    private List<Update> mExpectedUpdates = new ArrayList<>();

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

    public Query expect(Query query) {
        mExpectedQueries.add(query);
        return query;
    }

    public Query expectQuery(Uri contentUri) {
        return expect(new Query(contentUri));
    }

    public Query expectQuery(String contentUri) {
        return expectQuery(Uri.parse(contentUri));
    }

    public void expectTypeQuery(Uri uri, String type) {
        mExpectedTypeQueries.put(uri, type);
    }

    public void expectInsert(Uri contentUri, ContentValues contentValues, Uri resultUri) {
        mExpectedInserts.add(new Insert(contentUri, contentValues, resultUri));
    }

    public Update expectUpdate(Uri contentUri,
                               ContentValues contentValues,
                               @Nullable String selection,
                               @Nullable String[] selectionArgs) {
        Update update = new Update(contentUri, contentValues, selection, selectionArgs);
        mExpectedUpdates.add(update);
        return update;
    }

    public Delete expectDelete(Uri contentUri) {
        Delete delete = new Delete(contentUri);
        mExpectedDeletes.add(delete);
        return delete;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        if (mExpectedQueries.isEmpty()) {
            Assert.fail("Unexpected query: Actual:"
                    + queryToString(uri, projection, selection, selectionArgs, sortOrder));
        }

        for (Iterator<Query> iterator = mExpectedQueries.iterator(); iterator.hasNext();) {
            Query query = iterator.next();
            if (query.equals(uri, projection, selection, selectionArgs, sortOrder)) {
                query.mExecuted = true;
                if (!query.mAnyNumberOfTimes) {
                    iterator.remove();
                }
                return query.getResult(projection);
            }
        }

        Assert.fail("Incorrect query. Expected one of: " + mExpectedQueries + ". Actual: " +
                queryToString(uri, projection, selection, selectionArgs, sortOrder));
        return null;
    }

    @Override
    public String getType(Uri uri) {
        if (mExpectedTypeQueries.isEmpty()) {
            Assert.fail("Unexpected getType query: " + uri);
        }

        String mimeType = mExpectedTypeQueries.get(uri);
        if (mimeType != null) {
            return mimeType;
        }

        Assert.fail("Unknown mime type for: " + uri);
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (mExpectedInserts.isEmpty()) {
            Assert.fail("Unexpected insert. Actual: " + insertToString(uri, values));
        }
        for (Iterator<Insert> iterator = mExpectedInserts.iterator(); iterator.hasNext(); ) {
            Insert insert = iterator.next();
            if (insert.equals(uri, values)) {
                insert.mIsExecuted = true;
                if (!insert.mAnyNumberOfTimes) {
                    iterator.remove();
                }
                return insert.mResultUri;
            }
        }

        Assert.fail("Incorrect insert. Expected one of: " + mExpectedInserts + ". Actual: "
                + insertToString(uri, values));
        return null;
    }

    private String insertToString(Uri uri, ContentValues contentValues) {
        return "Insert { uri=" + uri + ", contentValues=" + contentValues + '}';
    }

    @Override
    public int update(Uri uri,
                      ContentValues values,
                      @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        if (mExpectedUpdates.isEmpty()) {
            Assert.fail("Unexpected update. Actual: "
                    + updateToString(uri, values, selection, selectionArgs));
        }
        for (Iterator<Update> iterator = mExpectedUpdates.iterator(); iterator.hasNext(); ) {
            Update update = iterator.next();
            if (update.equals(uri, values, selection, selectionArgs)) {
                update.mIsExecuted = true;
                if (!update.mAnyNumberOfTimes) {
                    iterator.remove();
                }
                return update.mRowsAffected;
            }
        }

        Assert.fail("Incorrect update. Expected one of: " + mExpectedUpdates + ". Actual: "
                + updateToString(uri, values, selection, selectionArgs));
        return - 1;
    }

    private String updateToString(Uri uri,
                                  ContentValues contentValues,
                                  @Nullable String selection,
                                  @Nullable String[] selectionArgs) {
        return "Update { uri=" + uri + ", contentValues=" + contentValues + ", selection=" +
                selection + ", selectionArgs" + Arrays.toString(selectionArgs) + '}';
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (mExpectedDeletes.isEmpty()) {
            Assert.fail("Unexpected delete. Actual: " + deleteToString(uri, selection,
                    selectionArgs));
        }
        for (Iterator<Delete> iterator = mExpectedDeletes.iterator(); iterator.hasNext(); ) {
            Delete delete = iterator.next();
            if (delete.equals(uri, selection, selectionArgs)) {
                delete.mIsExecuted = true;
                if (!delete.mAnyNumberOfTimes) {
                    iterator.remove();
                }
                return delete.mRowsAffected;
            }
        }
        Assert.fail("Incorrect delete. Expected one of: " + mExpectedDeletes + ". Actual: "
                + deleteToString(uri, selection, selectionArgs));
        return -1;
    }

    private String deleteToString(Uri uri, String selection, String[] selectionArgs) {
        return "Delete { uri=" + uri + ", selection=" + selection + ", selectionArgs"
                + Arrays.toString(selectionArgs) + '}';
    }

    private static String queryToString(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        StringBuilder sb = new StringBuilder();
        sb.append(uri == null ? "<Any Uri>" : uri).append(" ");
        if (projection != null) {
            sb.append(Arrays.toString(projection));
        } else {
            sb.append("[]");
        }
        if (selection != null) {
            sb.append(" selection: '").append(selection).append("'");
            if (selectionArgs != null) {
                sb.append(Arrays.toString(selectionArgs));
            } else {
                sb.append("[]");
            }
        }
        if (sortOrder != null) {
            sb.append(" sort: '").append(sortOrder).append("'");
        }
        return sb.toString();
    }

    public void verify() {
        verifyQueries();
        verifyInserts();
        verifyDeletes();
    }

    private void verifyQueries() {
        List<Query> missedQueries = new ArrayList<>();
        for (Query query : mExpectedQueries) {
            if (!query.mExecuted) {
                missedQueries.add(query);
            }
        }
        Assert.assertTrue("Not all expected queries have been called: " + missedQueries,
                missedQueries.isEmpty());
    }

    private void verifyInserts() {
        List<Insert> missedInserts = new ArrayList<>();
        for (Insert insert : mExpectedInserts) {
            if (!insert.mIsExecuted) {
                missedInserts.add(insert);
            }
        }
        Assert.assertTrue("Not all expected inserts have been called: " + missedInserts,
                missedInserts.isEmpty());
    }

    private void verifyDeletes() {
        List<Delete> missedDeletes = new ArrayList<>();
        for (Delete delete : mExpectedDeletes) {
            if (!delete.mIsExecuted) {
                missedDeletes.add(delete);
            }
        }
        Assert.assertTrue("Not all expected deletes have been called: " + missedDeletes,
                missedDeletes.isEmpty());
    }
}
