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

import android.accounts.Account;
import android.app.job.JobInfo;
import android.content.ContentResolver;
import android.content.ContentResolver.SyncExemption;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;

/**
 * Value type that represents a sync operation.
 * This holds all information related to a sync operation - both one off and periodic.
 * Data stored in this is used to schedule a job with the JobScheduler.
 * {@hide}
 */
public class SyncOperation {
    public static final String TAG = "SyncManager";

    /**
     * This is used in the {@link #sourcePeriodicId} field if the operation is not initiated by a failed
     * periodic sync.
     */
    public static final int NO_JOB_ID = -1;

    public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1;
    public static final int REASON_ACCOUNTS_UPDATED = -2;
    public static final int REASON_SERVICE_CHANGED = -3;
    public static final int REASON_PERIODIC = -4;
    /** Sync started because it has just been set to isSyncable. */
    public static final int REASON_IS_SYNCABLE = -5;
    /** Sync started because it has just been set to sync automatically. */
    public static final int REASON_SYNC_AUTO = -6;
    /** Sync started because master sync automatically has been set to true. */
    public static final int REASON_MASTER_SYNC_AUTO = -7;
    public static final int REASON_USER_START = -8;

    private static String[] REASON_NAMES = new String[] {
            "DataSettingsChanged",
            "AccountsUpdated",
            "ServiceChanged",
            "Periodic",
            "IsSyncable",
            "AutoSync",
            "MasterSyncAuto",
            "UserStart",
    };

    /** Identifying info for the target for this operation. */
    public final SyncStorageEngine.EndPoint target;
    public final int owningUid;
    public final String owningPackage;
    /** Why this sync was kicked off. {@link #REASON_NAMES} */
    public final int reason;
    /** Where this sync was initiated. */
    public final int syncSource;
    public final boolean allowParallelSyncs;
    public final Bundle extras;
    public final boolean isPeriodic;
    /** jobId of the periodic SyncOperation that initiated this one */
    public final int sourcePeriodicId;
    /** Operations are considered duplicates if keys are equal */
    public final String key;

    /** Poll frequency of periodic sync in milliseconds */
    public final long periodMillis;
    /** Flex time of periodic sync in milliseconds */
    public final long flexMillis;
    /** Descriptive string key for this operation */
    public String wakeLockName;
    /**
     * Used when duplicate pending syncs are present. The one with the lowest expectedRuntime
     * is kept, others are discarded.
     */
    public long expectedRuntime;

    /** Stores the number of times this sync operation failed and had to be retried. */
    int retries;

    /** jobId of the JobScheduler job corresponding to this sync */
    public int jobId;

    @SyncExemption
    public int syncExemptionFlag;

    public SyncOperation(Account account, int userId, int owningUid, String owningPackage,
                         int reason, int source, String provider, Bundle extras,
                         boolean allowParallelSyncs, @SyncExemption int syncExemptionFlag) {
        this(new SyncStorageEngine.EndPoint(account, provider, userId), owningUid, owningPackage,
                reason, source, extras, allowParallelSyncs, syncExemptionFlag);
    }

    private SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage,
            int reason, int source, Bundle extras, boolean allowParallelSyncs,
            @SyncExemption int syncExemptionFlag) {
        this(info, owningUid, owningPackage, reason, source, extras, allowParallelSyncs, false,
                NO_JOB_ID, 0, 0, syncExemptionFlag);
    }

    public SyncOperation(SyncOperation op, long periodMillis, long flexMillis) {
        this(op.target, op.owningUid, op.owningPackage, op.reason, op.syncSource,
                new Bundle(op.extras), op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId,
                periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE);
    }

    public SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage,
                         int reason, int source, Bundle extras, boolean allowParallelSyncs,
                         boolean isPeriodic, int sourcePeriodicId, long periodMillis,
                         long flexMillis, @SyncExemption int syncExemptionFlag) {
        this.target = info;
        this.owningUid = owningUid;
        this.owningPackage = owningPackage;
        this.reason = reason;
        this.syncSource = source;
        this.extras = new Bundle(extras);
        this.allowParallelSyncs = allowParallelSyncs;
        this.isPeriodic = isPeriodic;
        this.sourcePeriodicId = sourcePeriodicId;
        this.periodMillis = periodMillis;
        this.flexMillis = flexMillis;
        this.jobId = NO_JOB_ID;
        this.key = toKey();
        this.syncExemptionFlag = syncExemptionFlag;
    }

    /* Get a one off sync operation instance from a periodic sync. */
    public SyncOperation createOneTimeSyncOperation() {
        if (!isPeriodic) {
            return null;
        }
        SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, syncSource,
                new Bundle(extras), allowParallelSyncs, false, jobId /* sourcePeriodicId */,
                periodMillis, flexMillis, ContentResolver.SYNC_EXEMPTION_NONE);
        return op;
    }

    public SyncOperation(SyncOperation other) {
        target = other.target;
        owningUid = other.owningUid;
        owningPackage = other.owningPackage;
        reason = other.reason;
        syncSource = other.syncSource;
        allowParallelSyncs = other.allowParallelSyncs;
        extras = new Bundle(other.extras);
        wakeLockName = other.wakeLockName();
        isPeriodic = other.isPeriodic;
        sourcePeriodicId = other.sourcePeriodicId;
        periodMillis = other.periodMillis;
        flexMillis = other.flexMillis;
        this.key = other.key;
        syncExemptionFlag = other.syncExemptionFlag;
    }

    /**
     * All fields are stored in a corresponding key in the persistable bundle.
     *
     * {@link #extras} is a Bundle and can contain parcelable objects. But only the type Account
     * is allowed {@link ContentResolver#validateSyncExtrasBundle(Bundle)} that can't be stored in
     * a PersistableBundle. For every value of type Account with key 'key', we store a
     * PersistableBundle containing account information at key 'ACCOUNT:key'. The Account object
     * can be reconstructed using this.
     *
     * We put a flag with key 'SyncManagerJob', to identify while reconstructing a sync operation
     * from a bundle whether the bundle actually contains information about a sync.
     * @return A persistable bundle containing all information to re-construct the sync operation.
     */
    PersistableBundle toJobInfoExtras() {
        // This will be passed as extras bundle to a JobScheduler job.
        PersistableBundle jobInfoExtras = new PersistableBundle();

        PersistableBundle syncExtrasBundle = new PersistableBundle();
        for (String key: extras.keySet()) {
            Object value = extras.get(key);
            if (value instanceof Account) {
                Account account = (Account) value;
                PersistableBundle accountBundle = new PersistableBundle();
                accountBundle.putString("accountName", account.name);
                accountBundle.putString("accountType", account.type);
                // This is stored in jobInfoExtras so that we don't override a user specified
                // sync extra with the same key.
                jobInfoExtras.putPersistableBundle("ACCOUNT:" + key, accountBundle);
            } else if (value instanceof Long) {
                syncExtrasBundle.putLong(key, (Long) value);
            } else if (value instanceof Integer) {
                syncExtrasBundle.putInt(key, (Integer) value);
            } else if (value instanceof Boolean) {
                syncExtrasBundle.putBoolean(key, (Boolean) value);
            } else if (value instanceof Float) {
                syncExtrasBundle.putDouble(key, (double) (float) value);
            } else if (value instanceof Double) {
                syncExtrasBundle.putDouble(key, (Double) value);
            } else if (value instanceof String) {
                syncExtrasBundle.putString(key, (String) value);
            } else if (value == null) {
                syncExtrasBundle.putString(key, null);
            } else {
                Slog.e(TAG, "Unknown extra type.");
            }
        }
        jobInfoExtras.putPersistableBundle("syncExtras", syncExtrasBundle);

        jobInfoExtras.putBoolean("SyncManagerJob", true);

        jobInfoExtras.putString("provider", target.provider);
        jobInfoExtras.putString("accountName", target.account.name);
        jobInfoExtras.putString("accountType", target.account.type);
        jobInfoExtras.putInt("userId", target.userId);
        jobInfoExtras.putInt("owningUid", owningUid);
        jobInfoExtras.putString("owningPackage", owningPackage);
        jobInfoExtras.putInt("reason", reason);
        jobInfoExtras.putInt("source", syncSource);
        jobInfoExtras.putBoolean("allowParallelSyncs", allowParallelSyncs);
        jobInfoExtras.putInt("jobId", jobId);
        jobInfoExtras.putBoolean("isPeriodic", isPeriodic);
        jobInfoExtras.putInt("sourcePeriodicId", sourcePeriodicId);
        jobInfoExtras.putLong("periodMillis", periodMillis);
        jobInfoExtras.putLong("flexMillis", flexMillis);
        jobInfoExtras.putLong("expectedRuntime", expectedRuntime);
        jobInfoExtras.putInt("retries", retries);
        jobInfoExtras.putInt("syncExemptionFlag", syncExemptionFlag);
        return jobInfoExtras;
    }

    /**
     * Reconstructs a sync operation from an extras Bundle. Returns null if the bundle doesn't
     * contain a valid sync operation.
     */
    static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) {
        if (jobExtras == null) {
            return null;
        }
        String accountName, accountType;
        String provider;
        int userId, owningUid;
        String owningPackage;
        int reason, source;
        int initiatedBy;
        Bundle extras;
        boolean allowParallelSyncs, isPeriodic;
        long periodMillis, flexMillis;
        int syncExemptionFlag;

        if (!jobExtras.getBoolean("SyncManagerJob", false)) {
            return null;
        }

        accountName = jobExtras.getString("accountName");
        accountType = jobExtras.getString("accountType");
        provider = jobExtras.getString("provider");
        userId = jobExtras.getInt("userId", Integer.MAX_VALUE);
        owningUid = jobExtras.getInt("owningUid");
        owningPackage = jobExtras.getString("owningPackage");
        reason = jobExtras.getInt("reason", Integer.MAX_VALUE);
        source = jobExtras.getInt("source", Integer.MAX_VALUE);
        allowParallelSyncs = jobExtras.getBoolean("allowParallelSyncs", false);
        isPeriodic = jobExtras.getBoolean("isPeriodic", false);
        initiatedBy = jobExtras.getInt("sourcePeriodicId", NO_JOB_ID);
        periodMillis = jobExtras.getLong("periodMillis");
        flexMillis = jobExtras.getLong("flexMillis");
        syncExemptionFlag = jobExtras.getInt("syncExemptionFlag",
                ContentResolver.SYNC_EXEMPTION_NONE);
        extras = new Bundle();

        PersistableBundle syncExtras = jobExtras.getPersistableBundle("syncExtras");
        if (syncExtras != null) {
            extras.putAll(syncExtras);
        }

        for (String key: jobExtras.keySet()) {
            if (key!= null && key.startsWith("ACCOUNT:")) {
                String newKey = key.substring(8); // Strip off the 'ACCOUNT:' prefix.
                PersistableBundle accountsBundle = jobExtras.getPersistableBundle(key);
                Account account = new Account(accountsBundle.getString("accountName"),
                        accountsBundle.getString("accountType"));
                extras.putParcelable(newKey, account);
            }
        }

        Account account = new Account(accountName, accountType);
        SyncStorageEngine.EndPoint target =
                new SyncStorageEngine.EndPoint(account, provider, userId);
        SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, source,
                extras, allowParallelSyncs, isPeriodic, initiatedBy, periodMillis, flexMillis,
                syncExemptionFlag);
        op.jobId = jobExtras.getInt("jobId");
        op.expectedRuntime = jobExtras.getLong("expectedRuntime");
        op.retries = jobExtras.getInt("retries");
        return op;
    }

    /**
     * Determine whether if this sync operation is running, the provided operation would conflict
     * with it.
     * Parallel syncs allow multiple accounts to be synced at the same time.
     */
    boolean isConflict(SyncOperation toRun) {
        final SyncStorageEngine.EndPoint other = toRun.target;
        return target.account.type.equals(other.account.type)
                && target.provider.equals(other.provider)
                && target.userId == other.userId
                && (!allowParallelSyncs
                || target.account.name.equals(other.account.name));
    }

    boolean isReasonPeriodic() {
        return reason == REASON_PERIODIC;
    }

    boolean matchesPeriodicOperation(SyncOperation other) {
        return target.matchesSpec(other.target)
                && SyncManager.syncExtrasEquals(extras, other.extras, true)
                && periodMillis == other.periodMillis && flexMillis == other.flexMillis;
    }

    boolean isDerivedFromFailedPeriodicSync() {
        return sourcePeriodicId != NO_JOB_ID;
    }

    int findPriority() {
        if (isInitialization()) {
            return JobInfo.PRIORITY_SYNC_INITIALIZATION;
        } else if (isExpedited()) {
            return JobInfo.PRIORITY_SYNC_EXPEDITED;
        }
        return JobInfo.PRIORITY_DEFAULT;
    }

    private String toKey() {
        StringBuilder sb = new StringBuilder();
        sb.append("provider: ").append(target.provider);
        sb.append(" account {name=" + target.account.name
                + ", user="
                + target.userId
                + ", type="
                + target.account.type
                + "}");
        sb.append(" isPeriodic: ").append(isPeriodic);
        sb.append(" period: ").append(periodMillis);
        sb.append(" flex: ").append(flexMillis);
        sb.append(" extras: ");
        extrasToStringBuilder(extras, sb);
        return sb.toString();
    }

    @Override
    public String toString() {
        return dump(null, true, null, false);
    }

    public String toSafeString() {
        return dump(null, true, null, true);
    }

    String dump(PackageManager pm, boolean shorter, SyncAdapterStateFetcher appStates,
            boolean logSafe) {
        StringBuilder sb = new StringBuilder();
        sb.append("JobId=").append(jobId)
                .append(" ")
                .append(logSafe ? "***" : target.account.name)
                .append("/")
                .append(target.account.type)
                .append(" u")
                .append(target.userId)
                .append(" [")
                .append(target.provider)
                .append("] ");
        sb.append(SyncStorageEngine.SOURCES[syncSource]);
        if (expectedRuntime != 0) {
            sb.append(" ExpectedIn=");
            SyncManager.formatDurationHMS(sb,
                    (expectedRuntime - SystemClock.elapsedRealtime()));
        }
        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
            sb.append(" EXPEDITED");
        }
        switch (syncExemptionFlag) {
            case ContentResolver.SYNC_EXEMPTION_NONE:
                break;
            case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET:
                sb.append(" STANDBY-EXEMPTED");
                break;
            case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP:
                sb.append(" STANDBY-EXEMPTED(TOP)");
                break;
            default:
                sb.append(" ExemptionFlag=" + syncExemptionFlag);
                break;
        }
        sb.append(" Reason=");
        sb.append(reasonToString(pm, reason));
        if (isPeriodic) {
            sb.append(" (period=");
            SyncManager.formatDurationHMS(sb, periodMillis);
            sb.append(" flex=");
            SyncManager.formatDurationHMS(sb, flexMillis);
            sb.append(")");
        }
        if (retries > 0) {
            sb.append(" Retries=");
            sb.append(retries);
        }
        if (!shorter) {
            sb.append(" Owner={");
            UserHandle.formatUid(sb, owningUid);
            sb.append(" ");
            sb.append(owningPackage);
            if (appStates != null) {
                sb.append(" [");
                sb.append(appStates.getStandbyBucket(
                        UserHandle.getUserId(owningUid), owningPackage));
                sb.append("]");

                if (appStates.isAppActive(owningUid)) {
                    sb.append(" [ACTIVE]");
                }
            }
            sb.append("}");
            if (!extras.keySet().isEmpty()) {
                sb.append(" ");
                extrasToStringBuilder(extras, sb);
            }
        }
        return sb.toString();
    }

    static String reasonToString(PackageManager pm, int reason) {
        if (reason >= 0) {
            if (pm != null) {
                final String[] packages = pm.getPackagesForUid(reason);
                if (packages != null && packages.length == 1) {
                    return packages[0];
                }
                final String name = pm.getNameForUid(reason);
                if (name != null) {
                    return name;
                }
                return String.valueOf(reason);
            } else {
                return String.valueOf(reason);
            }
        } else {
            final int index = -reason - 1;
            if (index >= REASON_NAMES.length) {
                return String.valueOf(reason);
            } else {
                return REASON_NAMES[index];
            }
        }
    }

    boolean isInitialization() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
    }

    boolean isExpedited() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
    }

    boolean ignoreBackoff() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
    }

    boolean isNotAllowedOnMetered() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
    }

    boolean isManual() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
    }

    boolean isIgnoreSettings() {
        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
    }

    boolean isAppStandbyExempted() {
        return syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE;
    }

    static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
        if (bundle == null) {
            sb.append("null");
            return;
        }
        sb.append("[");
        for (String key : bundle.keySet()) {
            sb.append(key).append("=").append(bundle.get(key)).append(" ");
        }
        sb.append("]");
    }

    static String extrasToString(Bundle bundle) {
        final StringBuilder sb = new StringBuilder();
        extrasToStringBuilder(bundle, sb);
        return sb.toString();
    }

    String wakeLockName() {
        if (wakeLockName != null) {
            return wakeLockName;
        }
        return (wakeLockName = target.provider
                + "/" + target.account.type
                + "/" + target.account.name);
    }

    // TODO: Test this to make sure that casting to object doesn't lose the type info for EventLog.
    public Object[] toEventLog(int event) {
        Object[] logArray = new Object[4];
        logArray[1] = event;
        logArray[2] = syncSource;
        logArray[0] = target.provider;
        logArray[3] = target.account.name.hashCode();
        return logArray;
    }
}
