/*
 * Copyright (C) 2017 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.settings.backup;


import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.Settings.PrivacySettingsActivity;

import java.net.URISyntaxException;

/**
 * Helper class for {@link UserBackupSettingsActivity} that interacts with {@link IBackupManager}.
 */
public class BackupSettingsHelper {
    private static final String TAG = "BackupSettingsHelper";

    private IBackupManager mBackupManager = IBackupManager.Stub.asInterface(
            ServiceManager.getService(Context.BACKUP_SERVICE));

    private Context mContext;

    public BackupSettingsHelper(Context context) {
        mContext = context;
    }

    /**
     * If there is only one profile, show whether the backup is on or off.
     * Otherwise, show nothing.
     */
    public String getSummary() {
        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        if (userManager.getUserProfiles().size() == 1) {
            try {
                int resId = mBackupManager.isBackupEnabled() ? R.string.backup_summary_state_on
                    : R.string.backup_summary_state_off;
                return mContext.getText(resId).toString();
            } catch (RemoteException e) {
                Log.e(TAG, "Error getting isBackupEnabled", e);
            }
        }
        return null;
    }

    /**
     * Returns an intent to launch backup settings from backup transport if the intent was provided
     * by the transport. Otherwise returns the intent to launch the default backup settings screen.
     *
     * @return Intent for launching backup settings
     */
    public Intent getIntentForBackupSettings() {
        Intent intent;
        if (isIntentProvidedByTransport()) {
            intent = getIntentForBackupSettingsFromTransport();
        } else {
            Log.e(TAG, "Backup transport has not provided an intent"
                    + " or the component for the intent is not found!");
            intent = getIntentForDefaultBackupSettings();
        }
        return intent;
    }

    /**
     * Returns a label for the settings item that will point to the backup settings provided by
     * the transport. If no label was provided by transport, returns the default string.
     *
     * @return Label for the backup settings item.
     */
    public CharSequence getLabelForBackupSettings() {
        CharSequence label = getLabelFromBackupTransport();
        if (TextUtils.isEmpty(label)) {
            label = mContext.getString(R.string.privacy_settings_title);
        }
        return label;
    }

    /**
     * Returns a summary string for the settings item that will point to the backup settings
     * provided by the transport. If no summary was provided by transport, returns the default
     * string.
     *
     * @return Summary for the backup settings item.
     */
    public String getSummaryForBackupSettings() {
        String summary = getSummaryFromBackupTransport();
        if (summary == null) {
            summary = mContext.getString(R.string.backup_configure_account_default_summary);
        }
        return summary;
    }


    /**
     * Checks if the manufacturer provided an intent to launch its backup settings screen
     * in the config file.
     */
    public boolean isBackupProvidedByManufacturer() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Checking if intent provided by manufacturer");
        }
        String intentString =
                mContext.getResources().getString(R.string.config_backup_settings_intent);

        return intentString != null && !intentString.isEmpty();
    }

    /**
     * Returns the label for the backup settings item provided by the manufacturer.
     */
    public String getLabelProvidedByManufacturer() {
        return mContext.getResources().getString(R.string.config_backup_settings_label);
    }

    /**
     * Returns the intent to the backup settings screen provided by the manufacturer.
     */
    public Intent getIntentProvidedByManufacturer() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Getting a backup settings intent provided by manufacturer");
        }
        String intentString =
                mContext.getResources().getString(R.string.config_backup_settings_intent);
        if (intentString != null && !intentString.isEmpty()) {
            try {
                return Intent.parseUri(intentString, 0);
            } catch (URISyntaxException e) {
                Log.e(TAG, "Invalid intent provided by the manufacturer.", e);
            }
        }
        return null;
    }

    /**
     * Gets the intent from Backup transport and adds the extra depending on whether the user has
     * rights to see backup settings.
     *
     * @return Intent to launch Backup settings provided by the Backup transport.
     */
    @VisibleForTesting
    Intent getIntentForBackupSettingsFromTransport() {
        Intent intent = getIntentFromBackupTransport();
        if (intent != null) {
            intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, isBackupServiceActive());
        }
        return intent;
    }

    private Intent getIntentForDefaultBackupSettings() {
        return new Intent(mContext, PrivacySettingsActivity.class);
    }

    /**
     * Checks if the transport provided the intent to launch the backup settings and if that
     * intent resolves to an activity.
     */
    @VisibleForTesting
    boolean isIntentProvidedByTransport() {
        Intent intent = getIntentFromBackupTransport();
        return intent != null && intent.resolveActivity(mContext.getPackageManager()) != null;
    }

    /**
     * Gets an intent to launch the backup settings from the current transport using
     * {@link com.android.internal.backup.IBackupTransport#dataManagementIntent()} API.
     *
     * @return intent provided by transport or null if no intent was provided.
     */
    private Intent getIntentFromBackupTransport() {
        try {
            Intent intent =
                    mBackupManager.getDataManagementIntent(mBackupManager.getCurrentTransport());
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                if (intent != null) {
                    Log.d(TAG, "Parsed intent from backup transport: " + intent.toString());
                } else {
                    Log.d(TAG, "Received a null intent from backup transport");
                }
            }
            return intent;
        } catch (RemoteException e) {
            Log.e(TAG, "Error getting data management intent", e);
        }
        return null;
    }

    /** Checks if backup service is enabled for this user. */
    public boolean isBackupServiceActive() {
        boolean backupOkay;
        try {
            backupOkay = mBackupManager.isBackupServiceActive(UserHandle.myUserId());
        } catch (Exception e) {
            // things go wrong talking to the backup system => ignore and
            // pass the default 'false' as the "backup is a thing?" state.
            backupOkay = false;
        }
        return backupOkay;
    }

    @VisibleForTesting
    CharSequence getLabelFromBackupTransport() {
        try {
            CharSequence label =
                    mBackupManager.getDataManagementLabelForUser(
                            UserHandle.myUserId(), mBackupManager.getCurrentTransport());
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Received the backup settings label from backup transport: " + label);
            }
            return label;
        } catch (RemoteException e) {
            Log.e(TAG, "Error getting data management label", e);
        }
        return null;
    }

    @VisibleForTesting
    String getSummaryFromBackupTransport() {
        try {
            String summary =
                    mBackupManager.getDestinationString(mBackupManager.getCurrentTransport());
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG,
                        "Received the backup settings summary from backup transport: " + summary);
            }
            return summary;
        } catch (RemoteException e) {
            Log.e(TAG, "Error getting data management summary", e);
        }
        return null;
    }
}
