/*
 * Copyright (c) 2015 Diona Ltd.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of Diona
 * ("Confidential Information"). You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the license agreement you
 * entered into with Diona.
 */
package org.odk.collect.android.activities;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;

import java.util.HashMap;

/**
 * An Activity that handles permissions.
 */
public class PermissionActivity extends AppCompatActivity {

  private static final String ARG_PERMISSIONS = "permissions";
  /**
   * Key for an array of booleans for whether each permission was granted.
   */
  public static final String ARG_RESULTS = "success";
  public static final String ARG_REQUEST_CODE = "requestCode";
  private static final int REQUEST_CODE = 1;
  private int requestCode;

  public static Intent newIntent(final Context context, final String[] permissions, final int requestCode) {
    final Intent intent = new Intent(context, PermissionActivity.class);
    intent.putExtra(ARG_PERMISSIONS, permissions);
    intent.putExtra(ARG_REQUEST_CODE, requestCode);
    return intent;
  }

  @Override
  public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Intent intent = getIntent();
    if (intent == null) {
      cancelRequest();
      return;
    }
    requestCode = intent.getIntExtra(ARG_REQUEST_CODE, 0);
    final String[] permissions = intent.getStringArrayExtra(ARG_PERMISSIONS);
    if (permissions == null || permissions.length == 0) {
      cancelRequest();
      return;
    }

    ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE);
  }

  @Override
  public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final
  int[] grantResults) {
    final HashMap<String, Boolean> results = new HashMap<>();
    for (int i = 0; i < permissions.length; i++) {
      results.put(permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED);
    }
    sendResult(results);
  }

  private void cancelRequest() {
    final Bundle bundle = new Bundle();
    bundle.putInt(ARG_REQUEST_CODE, requestCode);
    setResult(RESULT_CANCELED);
    finish();
  }

  private void sendResult(final HashMap<String, Boolean> results) {
    final Intent resultIntent = new Intent();
    resultIntent.putExtra(ARG_RESULTS, results);
    resultIntent.putExtra(ARG_REQUEST_CODE, requestCode);
    setResult(RESULT_OK, resultIntent);
    finish();
  }

  /**
   * Requires a run time permission.
   */
  public interface PermissionRequired {

    /**
     * Mark we no longer want to receive permission updates.
     */
    void cancelWaitingForPermission();

    /**
     * @return {@code true} if we are waiting for a permission update, {@code false} if we are not.
     */
    boolean isWaitingForPermission();

    /**
     * Called when the widget receives a permission update.
     *
     * @param requestCode
     *     the code for the permission request.
     * @param results
     *     the results of the permission request.
     */
    void onPermissionsResult(final int requestCode, final HashMap<String, Boolean> results);
  }
}
