/*
 * Copyright (C) 2016 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.afwtest.common.nfcprovisioning;

import static com.android.afwtest.common.Constants.ACTION_SEND_NFC_BUMP;
import static com.android.afwtest.common.Constants.KEY_DEVICE_ADMIN_PKG_NAME;
import static com.android.afwtest.common.Constants.NFC_BUMP_FILE;
import static com.android.afwtest.common.Constants.SYSTEM_UTIL_PKG_NAME;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;

import com.android.afwtest.common.FileUtils;
import com.android.afwtest.common.PkgMgrUtils;

import java.util.Properties;

/**
 * NFC provisioning utils.
 */
public final class Utils {

    /**
     * Start provisioning by sending an intent to AfwThSystemUtil app.
     *
     * @param context {@link Context} object
     * @param nfcBumpFilePath path of the file containing the parameters to be sent in the Nfc bump
     * @return expected device admin package name
     */
    public static String startProvisioning(Context context, String nfcBumpFilePath)
            throws Exception {
        // Find Device Admin Package name
        Properties props = FileUtils.readPropertiesFromFile(nfcBumpFilePath);
        if (!props.containsKey(KEY_DEVICE_ADMIN_PKG_NAME)) {
            throw new RuntimeException(
                    KEY_DEVICE_ADMIN_PKG_NAME + " not specified in " + nfcBumpFilePath);
        }

        // Check if system util app is installed.
        String deviceAdminPkgName = props.getProperty(KEY_DEVICE_ADMIN_PKG_NAME);
        PackageManager pkgManager = context.getPackageManager();
        if (!PkgMgrUtils.isPkgInstalled(context, SYSTEM_UTIL_PKG_NAME)) {
            throw new RuntimeException(String.format("%s is not installed", SYSTEM_UTIL_PKG_NAME));
        }

        // Fire an intent to start nfc provisioning
        Intent intent = new Intent(ACTION_SEND_NFC_BUMP);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(NFC_BUMP_FILE, nfcBumpFilePath);

        context.startActivity(intent);

        // Return the expected device admin package name
        return deviceAdminPkgName;
    }
}
