/*
 * Copyright (C) 2007 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.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.accounts.Account;
import android.text.TextUtils;

import java.util.Map;

/**
 * The Sync provider stores information used in managing the syncing of the device,
 * including the history and pending syncs.
 * 
 * @hide
 */
public final class Sync {
    // utility class
    private Sync() {}

    /**
     * The content url for this provider.
     */
    public static final Uri CONTENT_URI = Uri.parse("content://sync");

    /**
     * Columns from the stats table.
     */
    public interface StatsColumns {
        /**
         * The sync account.
         * <P>Type: TEXT</P>
         */
        public static final String ACCOUNT = "account";

        /**
         * The sync account type.
         * <P>Type: TEXT</P>
         */
        public static final String ACCOUNT_TYPE = "account_type";

        /**
         * The content authority (contacts, calendar, etc.).
         * <P>Type: TEXT</P>
         */
        public static final String AUTHORITY = "authority";
    }

    /**
     * Provides constants and utility methods to access and use the stats table.
     */
    public static final class Stats implements BaseColumns, StatsColumns {

        // utility class
        private Stats() {}

        /**
         * The content url for this table.
         */
        public static final Uri CONTENT_URI =
                Uri.parse("content://sync/stats");

        /** Projection for the _id column in the stats table. */
        public static final String[] SYNC_STATS_PROJECTION = {_ID};
    }

    /**
     * Columns from the history table.
     */
    public interface HistoryColumns {
        /**
         * The ID of the stats row corresponding to this event.
         * <P>Type: INTEGER</P>
         */
        public static final String STATS_ID = "stats_id";

        /**
         * The source of the sync event (LOCAL, POLL, USER, SERVER).
         * <P>Type: INTEGER</P>
         */
        public static final String SOURCE = "source";

        /**
         * The type of sync event (START, STOP).
         * <P>Type: INTEGER</P>
         */
        public static final String EVENT = "event";

        /**
         * The time of the event.
         * <P>Type: INTEGER</P>
         */
        public static final String EVENT_TIME = "eventTime";

        /**
         * How long this event took. This is only valid if the EVENT is EVENT_STOP.
         * <P>Type: INTEGER</P>
         */
        public static final String ELAPSED_TIME = "elapsedTime";

        /**
         * Any additional message associated with this event.
         * <P>Type: TEXT</P>
         */
        public static final String MESG = "mesg";

        /**
         * How much activity was performed sending data to the server. This is sync adapter
         * specific, but usually is something like how many record update/insert/delete attempts
         * were carried out. This is only valid if the EVENT is EVENT_STOP.
         * <P>Type: INTEGER</P>
         */
        public static final String UPSTREAM_ACTIVITY = "upstreamActivity";

        /**
         * How much activity was performed while receiving data from the server.
         * This is sync adapter specific, but usually is something like how many
         * records were received from the server. This is only valid if the
         * EVENT is EVENT_STOP.
         * <P>Type: INTEGER</P>
         */
        public static final String DOWNSTREAM_ACTIVITY = "downstreamActivity";
    }

    /**
     * Columns from the history table.
     */
    public interface StatusColumns {
        /**
         * How many syncs were completed for this account and authority.
         * <P>Type: INTEGER</P>
         */
        public static final String NUM_SYNCS = "numSyncs";

        /**
         * How long all the events for this account and authority took.
         * <P>Type: INTEGER</P>
         */
        public static final String TOTAL_ELAPSED_TIME = "totalElapsedTime";

        /**
         * The number of syncs with SOURCE_POLL.
         * <P>Type: INTEGER</P>
         */
        public static final String NUM_SOURCE_POLL = "numSourcePoll";

        /**
         * The number of syncs with SOURCE_SERVER.
         * <P>Type: INTEGER</P>
         */
        public static final String NUM_SOURCE_SERVER = "numSourceServer";

        /**
         * The number of syncs with SOURCE_LOCAL.
         * <P>Type: INTEGER</P>
         */
        public static final String NUM_SOURCE_LOCAL = "numSourceLocal";

        /**
         * The number of syncs with SOURCE_USER.
         * <P>Type: INTEGER</P>
         */
        public static final String NUM_SOURCE_USER = "numSourceUser";

        /**
         * The time in ms that the last successful sync ended. Will be null if
         * there are no successful syncs. A successful sync is defined as one having
         * MESG=MESG_SUCCESS.
         * <P>Type: INTEGER</P>
         */
        public static final String LAST_SUCCESS_TIME = "lastSuccessTime";

        /**
         * The SOURCE of the last successful sync. Will be null if
         * there are no successful syncs. A successful sync is defined
         * as one having MESG=MESG_SUCCESS.
         * <P>Type: INTEGER</P>
         */
        public static final String LAST_SUCCESS_SOURCE = "lastSuccessSource";

        /**
         * The end time in ms of the last sync that failed since the last successful sync.
         * Will be null if there are no syncs or if the last one succeeded. A failed
         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
         * <P>Type: INTEGER</P>
         */
        public static final String LAST_FAILURE_TIME = "lastFailureTime";

        /**
         * The SOURCE of the last sync that failed since the last successful sync.
         * Will be null if there are no syncs or if the last one succeeded. A failed
         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
         * <P>Type: INTEGER</P>
         */
        public static final String LAST_FAILURE_SOURCE = "lastFailureSource";

        /**
         * The MESG of the last sync that failed since the last successful sync.
         * Will be null if there are no syncs or if the last one succeeded. A failed
         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
         * <P>Type: STRING</P>
         */
        public static final String LAST_FAILURE_MESG = "lastFailureMesg";

        /**
         * Is set to 1 if a sync is pending, 0 if not.
         * <P>Type: INTEGER</P>
         */
        public static final String PENDING = "pending";
    }

    /**
     * Provides constants and utility methods to access and use the history
     * table.
     */
    public static class History implements BaseColumns,
                                                 StatsColumns,
                                                 HistoryColumns {

        /**
         * The content url for this table.
         */
        public static final Uri CONTENT_URI =
                Uri.parse("content://sync/history");

        /** Enum value for a sync start event. */
        public static final int EVENT_START = 0;

        /** Enum value for a sync stop event. */
        public static final int EVENT_STOP = 1;

        // TODO: i18n -- grab these out of resources.
        /** String names for the sync event types. */
        public static final String[] EVENTS = { "START", "STOP" };

        /** Enum value for a server-initiated sync. */
        public static final int SOURCE_SERVER = 0;

        /** Enum value for a local-initiated sync. */
        public static final int SOURCE_LOCAL = 1;
        /**
         * Enum value for a poll-based sync (e.g., upon connection to
         * network)
         */
        public static final int SOURCE_POLL = 2;

        /** Enum value for a user-initiated sync. */
        public static final int SOURCE_USER = 3;

        // TODO: i18n -- grab these out of resources.
        /** String names for the sync source types. */
        public static final String[] SOURCES = { "SERVER",
                                                 "LOCAL",
                                                 "POLL",
                                                 "USER" };

        // Error types
        public static final int ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
        public static final int ERROR_AUTHENTICATION = 2;
        public static final int ERROR_IO = 3;
        public static final int ERROR_PARSE = 4;
        public static final int ERROR_CONFLICT = 5;
        public static final int ERROR_TOO_MANY_DELETIONS = 6;
        public static final int ERROR_TOO_MANY_RETRIES = 7;
        public static final int ERROR_INTERNAL = 8;

        // The MESG column will contain one of these or one of the Error types.
        public static final String MESG_SUCCESS = "success";
        public static final String MESG_CANCELED = "canceled";

        private static final String FINISHED_SINCE_WHERE_CLAUSE = EVENT + "=" + EVENT_STOP
                + " AND " + EVENT_TIME + ">? AND " + ACCOUNT + "=? AND " + ACCOUNT_TYPE + "=?"
                + " AND " + AUTHORITY + "=?";

        public static String mesgToString(String mesg) {
            if (MESG_SUCCESS.equals(mesg)) return mesg;
            if (MESG_CANCELED.equals(mesg)) return mesg;
            switch (Integer.parseInt(mesg)) {
                case ERROR_SYNC_ALREADY_IN_PROGRESS: return "already in progress";
                case ERROR_AUTHENTICATION: return "bad authentication";
                case ERROR_IO: return "network error";
                case ERROR_PARSE: return "parse error";
                case ERROR_CONFLICT: return "conflict detected";
                case ERROR_TOO_MANY_DELETIONS: return "too many deletions";
                case ERROR_TOO_MANY_RETRIES: return "too many retries";
                case ERROR_INTERNAL: return "internal error";
                default: return "unknown error";
            }
        }

        // utility class
        private History() {}

        /**
         * returns a cursor that queries the sync history in descending event time order
         * @param contentResolver the ContentResolver to use for the query
         * @return the cursor on the History table
         */
        public static Cursor query(ContentResolver contentResolver) {
            return contentResolver.query(CONTENT_URI, null, null, null, EVENT_TIME + " desc");
        }

        public static boolean hasNewerSyncFinished(ContentResolver contentResolver,
                Account account, String authority, long when) {
            Cursor c = contentResolver.query(CONTENT_URI, new String[]{_ID},
                    FINISHED_SINCE_WHERE_CLAUSE,
                    new String[]{Long.toString(when), account.mName, account.mType, authority},
                    null);
            try {
              return c.getCount() > 0;
            } finally {
                c.close();
            }
        }
    }

    /**
     * Provides constants and utility methods to access and use the authority history
     * table, which contains information about syncs aggregated by account and authority.
     * All the HistoryColumns except for EVENT are present, plus the AuthorityHistoryColumns.
     */
    public static class Status extends History implements StatusColumns {

        /**
         * The content url for this table.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sync/status");

        // utility class
        private Status() {}

        /**
         * returns a cursor that queries the authority sync history in descending event order of
         * ACCOUNT, AUTHORITY
         * @param contentResolver the ContentResolver to use for the query
         * @return the cursor on the AuthorityHistory table
         */
        public static Cursor query(ContentResolver contentResolver) {
            return contentResolver.query(CONTENT_URI, null, null, null,
                    ACCOUNT_TYPE + "," + ACCOUNT + "," + AUTHORITY);
        }

        public static class QueryMap extends ContentQueryMap {
            public QueryMap(ContentResolver contentResolver,
                    boolean keepUpdated,
                    Handler handlerForUpdateNotifications) {
                super(contentResolver.query(CONTENT_URI, null, null, null, null),
                        _ID, keepUpdated, handlerForUpdateNotifications);
            }

            public ContentValues get(Account account, String authority) {
                Map<String, ContentValues> rows = getRows();
                for (ContentValues values : rows.values()) {
                    if (values.getAsString(ACCOUNT).equals(account.mName)
                            && values.getAsString(ACCOUNT_TYPE).equals(account.mType)
                            && values.getAsString(AUTHORITY).equals(authority)) {
                        return values;
                    }
                }
                return null;
            }
        }
    }

    /**
     * Provides constants and utility methods to access and use the pending syncs table
     */
    public static final class Pending implements BaseColumns,
                                                 StatsColumns {

        /**
         * The content url for this table.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sync/pending");

        // utility class
        private Pending() {}

        public static class QueryMap extends ContentQueryMap {
            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
                    Handler handlerForUpdateNotifications) {
                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
                        handlerForUpdateNotifications);
            }

            public boolean isPending(Account account, String authority) {
                Map<String, ContentValues> rows = getRows();
                for (ContentValues values : rows.values()) {
                    if (values.getAsString(ACCOUNT).equals(account.mName)
                            && values.getAsString(ACCOUNT_TYPE).equals(account.mType)
                            && values.getAsString(AUTHORITY).equals(authority)) {
                        return true;
                    }
                }
                return false;
            }
        }
    }

    /**
     * Columns from the history table.
     */
    public interface ActiveColumns {
        /**
         * The wallclock time of when the active sync started.
         * <P>Type: INTEGER</P>
         */
        public static final String START_TIME = "startTime";
    }

    /**
     * Provides constants and utility methods to access and use the pending syncs table
     */
    public static final class Active implements BaseColumns,
                                                StatsColumns,
                                                ActiveColumns {

        /**
         * The content url for this table.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sync/active");

        // utility class
        private Active() {}

        public static class QueryMap extends ContentQueryMap {
            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
                    Handler handlerForUpdateNotifications) {
                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
                        handlerForUpdateNotifications);
            }

            public ContentValues getActiveSyncInfo() {
                Map<String, ContentValues> rows = getRows();
                for (ContentValues values : rows.values()) {
                    return values;
                }
                return null;
            }

            public Account getSyncingAccount() {
                ContentValues values = getActiveSyncInfo();
                if (values == null || TextUtils.isEmpty(values.getAsString(ACCOUNT))) {
                    return null;
                }
                return new Account(values.getAsString(ACCOUNT), values.getAsString(ACCOUNT_TYPE));
            }

            public String getSyncingAuthority() {
                ContentValues values = getActiveSyncInfo();
                return (values == null) ? null : values.getAsString(AUTHORITY);
            }

            public long getSyncStartTime() {
                ContentValues values = getActiveSyncInfo();
                return (values == null) ? -1 : values.getAsLong(START_TIME);
            }
        }
    }

    /**
     * Columns in the settings table, which holds key/value pairs of settings.
     */
    public interface SettingsColumns {
        /**
         * The key of the setting
         * <P>Type: TEXT</P>
         */
        public static final String KEY = "name";

        /**
         * The value of the settings
         * <P>Type: TEXT</P>
         */
        public static final String VALUE = "value";
    }

    /**
     * Provides constants and utility methods to access and use the settings
     * table.
     */
    public static final class Settings implements BaseColumns, SettingsColumns {
        /**
         * The Uri of the settings table. This table behaves a little differently than
         * normal tables. Updates are not allowed, only inserts, and inserts cause a replace
         * to be performed, which first deletes the row if it is already present.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sync/settings");

        /** controls whether or not the device listens for sync tickles */
        public static final String SETTING_LISTEN_FOR_TICKLES = "listen_for_tickles";

        /** controls whether or not the individual provider is synced when tickles are received */
        public static final String SETTING_SYNC_PROVIDER_PREFIX = "sync_provider_";

        /** query column project */
        private static final String[] PROJECTION = { KEY, VALUE };

        /**
         * Convenience function for updating a single settings value as a
         * boolean. This will either create a new entry in the table if the
         * given name does not exist, or modify the value of the existing row
         * with that name.  Note that internally setting values are always
         * stored as strings, so this function converts the given value to a
         * string before storing it.
         *
         * @param contentResolver the ContentResolver to use to access the settings table
         * @param name The name of the setting to modify.
         * @param val The new value for the setting.
         */
        static private void putBoolean(ContentResolver contentResolver, String name, boolean val) {
            ContentValues values = new ContentValues();
            values.put(KEY, name);
            values.put(VALUE, Boolean.toString(val));
            // this insert is translated into an update by the underlying Sync provider
            contentResolver.insert(CONTENT_URI, values);
        }

        /**
         * Convenience function for getting a setting value as a boolean without using the
         * QueryMap for light-weight setting querying.
         * @param contentResolver The ContentResolver for querying the setting.
         * @param name The name of the setting to query
         * @param def The default value for the setting.
         * @return The value of the setting.
         */
        static public boolean getBoolean(ContentResolver contentResolver,
                String name, boolean def) {
            Cursor cursor = contentResolver.query(
                    CONTENT_URI,
                    PROJECTION,
                    KEY + "=?",
                    new String[] { name },
                    null);
            try {
                if (cursor != null && cursor.moveToFirst()) {
                    return Boolean.parseBoolean(cursor.getString(1));
                }
            } finally {
                if (cursor != null) cursor.close();
            }
            return def;
        }

        /**
         * A convenience method to set whether or not the provider is synced when
         * it receives a network tickle.
         *
         * @param contentResolver the ContentResolver to use to access the settings table
         * @param providerName the provider whose behavior is being controlled
         * @param sync true if the provider should be synced when tickles are received for it
         */
        static public void setSyncProviderAutomatically(ContentResolver contentResolver,
                String providerName, boolean sync) {
            putBoolean(contentResolver, SETTING_SYNC_PROVIDER_PREFIX + providerName, sync);
        }

        /**
         * A convenience method to set whether or not the device should listen to tickles.
         *
         * @param contentResolver the ContentResolver to use to access the settings table
         * @param flag true if it should listen.
         */
        static public void setListenForNetworkTickles(ContentResolver contentResolver,
                boolean flag) {
            putBoolean(contentResolver, SETTING_LISTEN_FOR_TICKLES, flag);
        }

        public static class QueryMap extends ContentQueryMap {
            private ContentResolver mContentResolver;

            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
                    Handler handlerForUpdateNotifications) {
                super(contentResolver.query(CONTENT_URI, null, null, null, null), KEY, keepUpdated,
                        handlerForUpdateNotifications);
                mContentResolver = contentResolver;
            }

            /**
             * Check if the provider should be synced when a network tickle is received
             * @param providerName the provider whose setting we are querying
             * @return true of the provider should be synced when a network tickle is received
             */
            public boolean getSyncProviderAutomatically(String providerName) {
                return getBoolean(SETTING_SYNC_PROVIDER_PREFIX + providerName, true);
            }

            /**
             * Set whether or not the provider is synced when it receives a network tickle.
             *
             * @param providerName the provider whose behavior is being controlled
             * @param sync true if the provider should be synced when tickles are received for it
             */
            public void setSyncProviderAutomatically(String providerName, boolean sync) {
                Settings.setSyncProviderAutomatically(mContentResolver, providerName, sync);
            }

            /**
             * Set whether or not the device should listen for tickles.
             *
             * @param flag true if it should listen.
             */
            public void setListenForNetworkTickles(boolean flag) {
                Settings.setListenForNetworkTickles(mContentResolver, flag);
            }

            /**
             * Check if the device should listen to tickles.

             * @return true if it should
             */
            public boolean getListenForNetworkTickles() {
                return getBoolean(SETTING_LISTEN_FOR_TICKLES, true);
            }

            /**
             * Convenience function for retrieving a single settings value
             * as a boolean.
             *
             * @param name The name of the setting to retrieve.
             * @param def Value to return if the setting is not defined.
             * @return The setting's current value, or 'def' if it is not defined.
             */
            private boolean getBoolean(String name, boolean def) {
                ContentValues values = getValues(name);
                return values != null ? values.getAsBoolean(VALUE) : def;
            }
        }
    }
}
