/*
 * 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.provider;

import android.net.Uri;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.content.ContentProviderOperation;
import android.content.ContentUris;
import android.accounts.Account;
import android.database.Cursor;
import android.os.RemoteException;
import android.util.Pair;

/**
 * The ContentProvider contract for associating data with ana data array account.
 * This may be used by providers that want to store this data in a standard way.
 */
public class SyncStateContract {
    public interface Columns extends BaseColumns {
        /**
         * A reference to the name of the account to which this data belongs
         * <P>Type: STRING</P>
         */
        public static final String ACCOUNT_NAME = "account_name";

        /**
         * A reference to the type of the account to which this data belongs
         * <P>Type: STRING</P>
         */
        public static final String ACCOUNT_TYPE = "account_type";

        /**
         * The sync data associated with this account.
         * <P>Type: NONE</P>
         */
        public static final String DATA = "data";
    }

    public static class Constants implements Columns {
        public static final String CONTENT_DIRECTORY = "syncstate";
    }

    public static final class Helpers {
        private static final String[] DATA_PROJECTION = new String[]{Columns.DATA, Columns._ID};
        private static final String SELECT_BY_ACCOUNT =
                Columns.ACCOUNT_NAME + "=? AND " + Columns.ACCOUNT_TYPE + "=?";

        /**
         * Get the sync state that is associated with the account or null.
         * @param provider the {@link ContentProviderClient} that is to be used to communicate
         * with the {@link android.content.ContentProvider} that contains the sync state.
         * @param uri the uri of the sync state
         * @param account the {@link Account} whose sync state should be returned
         * @return the sync state or null if there is no sync state associated with the account
         * @throws RemoteException if there is a failure communicating with the remote
         * {@link android.content.ContentProvider}
         */
        public static byte[] get(ContentProviderClient provider, Uri uri,
                Account account) throws RemoteException {
            Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
                    new String[]{account.name, account.type}, null);

            // Unable to query the provider
            if (c == null) {
                throw new RemoteException();
            }

            try {
                if (c.moveToNext()) {
                    return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
                }
            } finally {
                c.close();
            }
            return null;
        }

        /**
         * Assigns the data array as the sync state for the given account.
         * @param provider the {@link ContentProviderClient} that is to be used to communicate
         * with the {@link android.content.ContentProvider} that contains the sync state.
         * @param uri the uri of the sync state
         * @param account the {@link Account} whose sync state should be set
         * @param data the byte[] that contains the sync state
         * @throws RemoteException if there is a failure communicating with the remote
         * {@link android.content.ContentProvider}
         */
        public static void set(ContentProviderClient provider, Uri uri,
                Account account, byte[] data) throws RemoteException {
            ContentValues values = new ContentValues();
            values.put(Columns.DATA, data);
            values.put(Columns.ACCOUNT_NAME, account.name);
            values.put(Columns.ACCOUNT_TYPE, account.type);
            provider.insert(uri, values);
        }

        public static Uri insert(ContentProviderClient provider, Uri uri,
                Account account, byte[] data) throws RemoteException {
            ContentValues values = new ContentValues();
            values.put(Columns.DATA, data);
            values.put(Columns.ACCOUNT_NAME, account.name);
            values.put(Columns.ACCOUNT_TYPE, account.type);
            return provider.insert(uri, values);
        }

        public static void update(ContentProviderClient provider, Uri uri, byte[] data)
                throws RemoteException {
            ContentValues values = new ContentValues();
            values.put(Columns.DATA, data);
            provider.update(uri, values, null, null);
        }

        public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Uri uri,
                Account account) throws RemoteException {
            Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
                    new String[]{account.name, account.type}, null);

            if (c == null) {
                throw new RemoteException();
            }

            try {
                if (c.moveToNext()) {
                    long rowId = c.getLong(1);
                    byte[] blob = c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
                    return Pair.create(ContentUris.withAppendedId(uri, rowId), blob);
                }
            } finally {
                c.close();
            }
            return null;
        }

        /**
         * Creates and returns a ContentProviderOperation that assigns the data array as the
         * sync state for the given account.
         * @param uri the uri of the sync state
         * @param account the {@link Account} whose sync state should be set
         * @param data the byte[] that contains the sync state
         * @return the new ContentProviderOperation that assigns the data array as the
         * account's sync state
         */
        public static ContentProviderOperation newSetOperation(Uri uri,
                Account account, byte[] data) {
            ContentValues values = new ContentValues();
            values.put(Columns.DATA, data);
            return ContentProviderOperation
                    .newInsert(uri)
                    .withValue(Columns.ACCOUNT_NAME, account.name)
                    .withValue(Columns.ACCOUNT_TYPE, account.type)
                    .withValues(values)
                    .build();
        }

        /**
         * Creates and returns a ContentProviderOperation that assigns the data array as the
         * sync state for the given account.
         * @param uri the uri of the specific sync state to set
         * @param data the byte[] that contains the sync state
         * @return the new ContentProviderOperation that assigns the data array as the
         * account's sync state
         */
        public static ContentProviderOperation newUpdateOperation(Uri uri, byte[] data) {
            ContentValues values = new ContentValues();
            values.put(Columns.DATA, data);
            return ContentProviderOperation
                    .newUpdate(uri)
                    .withValues(values)
                    .build();
        }
    }
}
