/*
** Copyright 2006, 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.providers.subscribedfeeds;

import android.content.UriMatcher;
import android.content.*;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.SubscribedFeeds;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;

import java.util.Collections;
import java.util.Map;
import java.util.HashMap;

/**
 * Manages a list of feeds for which this client is interested in receiving
 * change notifications.
 */
public class SubscribedFeedsProvider extends AbstractSyncableContentProvider {
    private static final String TAG = "SubscribedFeedsProvider";
    private static final String DATABASE_NAME = "subscribedfeeds.db";
    private static final int DATABASE_VERSION = 11;

    private static final int FEEDS = 1;
    private static final int FEED_ID = 2;
    private static final int DELETED_FEEDS = 3;
    private static final int ACCOUNTS = 4;

    private static final Map<String, String> ACCOUNTS_PROJECTION_MAP;

    private static final UriMatcher sURLMatcher =
            new UriMatcher(UriMatcher.NO_MATCH);

    private static String sFeedsTable = "feeds";
    private static Uri sFeedsUrl =
            Uri.parse("content://subscribedfeeds/feeds/");
    private static String sDeletedFeedsTable = "_deleted_feeds";
    private static Uri sDeletedFeedsUrl =
            Uri.parse("content://subscribedfeeds/deleted_feeds/");

    public SubscribedFeedsProvider() {
        super(DATABASE_NAME, DATABASE_VERSION, sFeedsUrl);
    }

    static {
        sURLMatcher.addURI("subscribedfeeds", "feeds", FEEDS);
        sURLMatcher.addURI("subscribedfeeds", "feeds/#", FEED_ID);
        sURLMatcher.addURI("subscribedfeeds", "deleted_feeds", DELETED_FEEDS);
        sURLMatcher.addURI("subscribedfeeds", "accounts", ACCOUNTS);
    }

    @Override
    protected boolean upgradeDatabase(SQLiteDatabase db,
            int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion +
                " to " + newVersion +
                ", which will destroy all old data");
        db.execSQL("DROP TRIGGER IF EXISTS feed_cleanup");
        db.execSQL("DROP TABLE IF EXISTS _deleted_feeds");
        db.execSQL("DROP TABLE IF EXISTS feeds");
        bootstrapDatabase(db);
        return false; // this was lossy
    }

    @Override
    protected void bootstrapDatabase(SQLiteDatabase db) {
        super.bootstrapDatabase(db);
        db.execSQL("CREATE TABLE feeds (" +
                    "_id INTEGER PRIMARY KEY," +
                    "_sync_account TEXT," + // From the sync source
                    "_sync_account_type TEXT," + // From the sync source
                    "_sync_id TEXT," + // From the sync source
                    "_sync_time TEXT," + // From the sync source
                    "_sync_version TEXT," + // From the sync source
                    "_sync_local_id INTEGER," + // Used while syncing,
                                                // never stored persistently
                    "_sync_dirty INTEGER," + // if syncable, set if the record
                                             // has local, unsynced, changes
                    "_sync_mark INTEGER," + // Used to filter out new rows
                    "feed TEXT," +
                    "authority TEXT," +
                    "service TEXT" +
                    ");");

        // Trigger to completely remove feeds data when they're deleted
        db.execSQL("CREATE TRIGGER feed_cleanup DELETE ON feeds " +
                    "WHEN old._sync_id is not null " +
                    "BEGIN " +
                        "INSERT INTO _deleted_feeds " +
                            "(_sync_id, _sync_account, _sync_account_type, _sync_version) " +
                            "VALUES (old._sync_id, old._sync_account, old._sync_account_type, " +
                            "old._sync_version);" +
                    "END");

        db.execSQL("CREATE TABLE _deleted_feeds (" +
                    "_sync_version TEXT," + // From the sync source
                    "_sync_id TEXT," +
                    (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
                    "_sync_account TEXT," +
                    "_sync_account_type TEXT," +
                    "_sync_mark INTEGER, " + // Used to filter out new rows
                    "UNIQUE(_sync_id))");
    }

    @Override
    protected void onDatabaseOpened(SQLiteDatabase db) {
        db.markTableSyncable("feeds", "_deleted_feeds");
    }

    @Override
    protected Iterable<FeedMerger> getMergers() {
        return Collections.singletonList(new FeedMerger());
    }

    @Override
    public String getType(Uri url) {
        int match = sURLMatcher.match(url);
        switch (match) {
            case FEEDS:
                return SubscribedFeeds.Feeds.CONTENT_TYPE;
            case FEED_ID:
                return SubscribedFeeds.Feeds.CONTENT_ITEM_TYPE;
            default:
                throw new IllegalArgumentException("Unknown URL");
        }
    }

    @Override
    public Cursor queryInternal(Uri url, String[] projection,
            String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();


        // Generate the body of the query
        int match = sURLMatcher.match(url);

        if (Config.LOGV) Log.v(TAG, "SubscribedFeedsProvider.query: url=" +
                url + ", match is " + match);

        switch (match) {
            case FEEDS:
                qb.setTables(sFeedsTable);
                break;
            case DELETED_FEEDS:
                if (!isTemporary()) {
                    throw new UnsupportedOperationException();
                }
                qb.setTables(sDeletedFeedsTable);
                break;
            case ACCOUNTS:
                qb.setTables(sFeedsTable);
                qb.setDistinct(true);
                qb.setProjectionMap(ACCOUNTS_PROJECTION_MAP);
                return qb.query(getDatabase(), projection, selection, selectionArgs,
                        SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + ","
                                + SubscribedFeeds.Feeds._SYNC_ACCOUNT, null, sortOrder);
            case FEED_ID:
                qb.setTables(sFeedsTable);
                qb.appendWhere(sFeedsTable + "._id=");
                qb.appendWhere(url.getPathSegments().get(1));
                break;
            default:
                throw new IllegalArgumentException("Unknown URL " + url);
        }

        // run the query
        return qb.query(getDatabase(), projection, selection, selectionArgs,
                null, null, sortOrder);
    }

    @Override
    public Uri insertInternal(Uri url, ContentValues initialValues) {
        final SQLiteDatabase db = getDatabase();
        Uri resultUri = null;
        long rowID;

        int match = sURLMatcher.match(url);
        switch (match) {
            case FEEDS:
                ContentValues values = new ContentValues(initialValues);
                values.put(SubscribedFeeds.Feeds._SYNC_DIRTY, 1);
                rowID = db.insert(sFeedsTable, "feed", values);
                if (rowID > 0) {
                    resultUri = Uri.parse(
                            "content://subscribedfeeds/feeds/" + rowID);
                }
                break;

            case DELETED_FEEDS:
                if (!isTemporary()) {
                    throw new UnsupportedOperationException();
                }
                rowID = db.insert(sDeletedFeedsTable, "_sync_id",
                        initialValues);
                if (rowID > 0) {
                    resultUri = Uri.parse(
                            "content://subscribedfeeds/deleted_feeds/" + rowID);
                }
                break;

            default:
                throw new UnsupportedOperationException(
                        "Cannot insert into URL: " + url);
        }

        return resultUri;
    }

    @Override
    public int deleteInternal(Uri url, String userWhere, String[] whereArgs) {
        final SQLiteDatabase db = getDatabase();
        String changedItemId;

        switch (sURLMatcher.match(url)) {
            case FEEDS:
                changedItemId = null;
                break;
            case FEED_ID:
                changedItemId = url.getPathSegments().get(1);
                break;
            default:
                throw new UnsupportedOperationException(
                        "Cannot delete that URL: " + url);
        }

        String where = addIdToWhereClause(changedItemId, userWhere);
        return db.delete(sFeedsTable, where, whereArgs);
    }

    @Override
    public int updateInternal(Uri url, ContentValues initialValues,
            String userWhere, String[] whereArgs) {
        final SQLiteDatabase db = getDatabase();
        ContentValues values = new ContentValues(initialValues);
        values.put(SubscribedFeeds.Feeds._SYNC_DIRTY, 1);

        String changedItemId;
        switch (sURLMatcher.match(url)) {
            case FEEDS:
                changedItemId = null;
                break;

            case FEED_ID:
                changedItemId = url.getPathSegments().get(1);
                break;

            default:
                throw new UnsupportedOperationException(
                        "Cannot update URL: " + url);
        }

        String where = addIdToWhereClause(changedItemId, userWhere);
        return db.update(sFeedsTable, values, where, whereArgs);
    }

    private static String addIdToWhereClause(String id, String where) {
        if (id != null) {
            StringBuilder whereSb = new StringBuilder("_id=");
            whereSb.append(id);
            if (!TextUtils.isEmpty(where)) {
                whereSb.append(" AND (");
                whereSb.append(where);
                whereSb.append(')');
            }
            return whereSb.toString();
        } else {
            return where;
        }
    }

    private class FeedMerger extends AbstractTableMerger {
        private ContentValues mValues = new ContentValues();
        FeedMerger() {
            super(getDatabase(), sFeedsTable, sFeedsUrl, sDeletedFeedsTable, sDeletedFeedsUrl);
        }

        @Override
        protected void notifyChanges() {
            getContext().getContentResolver().notifyChange(
                    sFeedsUrl, null /* data change observer */,
                    false /* do not sync to network */);
        }

        @Override
        public void insertRow(ContentProvider diffs, Cursor diffsCursor) {
            final SQLiteDatabase db = getDatabase();
            // We don't ever want to add entries from the server, instead
            // we want to tell the server to delete any entries we receive
            // from the server that aren't already known by the client.
            mValues.clear();
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_ID, mValues);
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_ACCOUNT, mValues);
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, mValues);
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_VERSION, mValues);
            db.replace(mDeletedTable, SubscribedFeeds.Feeds._SYNC_ID, mValues);
        }

        @Override
        public void updateRow(long localPersonID, ContentProvider diffs,
                Cursor diffsCursor) {
            updateOrResolveRow(localPersonID, null, diffs, diffsCursor, false);
        }

        @Override
        public void resolveRow(long localPersonID, String syncID,
                ContentProvider diffs, Cursor diffsCursor) {
            updateOrResolveRow(localPersonID, syncID, diffs, diffsCursor, true);
        }

        protected void updateOrResolveRow(long localPersonID, String syncID,
                ContentProvider diffs, Cursor diffsCursor, boolean conflicts) {
            mValues.clear();
            // only copy over the fields that the server owns
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_ID, mValues);
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_TIME, mValues);
            DatabaseUtils.cursorStringToContentValues(diffsCursor,
                    SubscribedFeeds.Feeds._SYNC_VERSION, mValues);
            mValues.put(SubscribedFeeds.Feeds._SYNC_DIRTY, conflicts ? 1 : 0);
            final SQLiteDatabase db = getDatabase();
            db.update(mTable, mValues,
                    SubscribedFeeds.Feeds._ID + '=' + localPersonID, null);
        }

        @Override
        public void deleteRow(Cursor localCursor) {
            // Since the client is the authority we don't actually delete
            // the row when the server says it has been deleted. Instead
            // we break the association with the server by clearing out
            // the id, time, and version, then we mark it dirty so that
            // it will be synced back to the server.
            long localPersonId = localCursor.getLong(localCursor.getColumnIndex(
                    SubscribedFeeds.Feeds._ID));
            mValues.clear();
            mValues.put(SubscribedFeeds.Feeds._SYNC_DIRTY, 1);
            mValues.put(SubscribedFeeds.Feeds._SYNC_ID, (String) null);
            mValues.put(SubscribedFeeds.Feeds._SYNC_TIME, (Long) null);
            mValues.put(SubscribedFeeds.Feeds._SYNC_VERSION, (String) null);
            final SQLiteDatabase db = getDatabase();
            db.update(mTable, mValues, SubscribedFeeds.Feeds._ID + '=' + localPersonId, null);
            localCursor.moveToNext();
        }
    }

    static {
        Map<String, String> map;

        map = new HashMap<String, String>();
        ACCOUNTS_PROJECTION_MAP = map;
        map.put(SubscribedFeeds.Accounts._COUNT, "COUNT(*) AS _count");
        map.put(SubscribedFeeds.Accounts._SYNC_ACCOUNT, SubscribedFeeds.Accounts._SYNC_ACCOUNT);
        map.put(SubscribedFeeds.Accounts._SYNC_ACCOUNT_TYPE,
                SubscribedFeeds.Accounts._SYNC_ACCOUNT_TYPE);
    }
}
