package com.github.yasevich.secrets;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
import android.widget.EditText;

import com.github.yasevich.secrets.algorithm.OperationMode;
import com.github.yasevich.secrets.databinding.ActivityFingerprintStoreBinding;
import com.github.yasevich.secrets.databinding.ViewLogBinding;
import com.github.yasevich.secrets.databinding.ViewStoreActionsBinding;
import com.github.yasevich.secrets.store.FingerprintStore;
import com.github.yasevich.secrets.store.Store;

import javax.crypto.Cipher;

@TargetApi(Build.VERSION_CODES.M)
public final class FingerprintStoreActivity extends StoreActivity {

    @NonNull
    private final Store store = new FingerprintStore();

    private FingerprintManagerCompat fingerprintManager;

    private ActivityFingerprintStoreBinding binding;

    @OperationMode
    private int operationMode = Cipher.ENCRYPT_MODE;

    public static void start(@NonNull Context context) {
        context.startActivity(new Intent(context, FingerprintStoreActivity.class));
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_fingerprint_store);

        fingerprintManager = FingerprintManagerCompat.from(this);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        authenticate();
    }

    @NonNull
    @Override
    protected Store getStore() {
        return store;
    }

    @Override
    protected boolean isStoreActionsEnabled() {
        return fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints();
    }

    @NonNull
    @Override
    protected EditText getSecret() {
        return binding.secret;
    }

    @NonNull
    @Override
    protected ViewStoreActionsBinding getStoreActionsBinding() {
        return binding.storeActions;
    }

    @NonNull
    @Override
    protected ViewLogBinding getLogBinding() {
        return binding.log;
    }

    @Override
    protected void onOperation(@OperationMode int mode) {
        super.onOperation(mode);
        operationMode = mode == Cipher.ENCRYPT_MODE ? Cipher.DECRYPT_MODE : Cipher.ENCRYPT_MODE;
    }

    private void authenticate() {
        fingerprintManager.authenticate(null, 0, null, new FingerprintManagerCompat.AuthenticationCallback() {
            @Override
            public void onAuthenticationFailed() {
                log("authentication failed");
            }

            @Override
            public void onAuthenticationError(int errMsgId, CharSequence errString) {
                log("authentication error: " + errMsgId + ' ' + errString);
            }

            @Override
            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                log("authentication help: " + helpMsgId + ' ' + helpString);
            }

            @Override
            public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                log("authentication succeeded");
                if (operationMode == Cipher.ENCRYPT_MODE) {
                    binding.storeActions.encrypt.callOnClick();
                } else {
                    binding.storeActions.decrypt.callOnClick();
                }
                authenticate();
            }
        }, null);
    }
}

@@ -386,16 +386,65 @@
 Compat;%0A
+import android.support.v4.os.CancellationSignal;%0A
 import a
@@ -467,16 +467,16 @@
 itText;%0A
-
 %0Aimport 
@@ -1109,16 +1109,67 @@
 Manager;
+%0A    private CancellationSignal cancellationSignal;
 %0A%0A    pr
@@ -1768,126 +1768,200 @@
 d on
-PostCreate(@Nullable Bundle savedInstanceState) %7B%0A        super.onPostCreate(savedInstanceState);%0A        authenticate
+Resume() %7B%0A        super.onResume();%0A        cancellationSignal = authenticate();%0A    %7D%0A%0A    @Override%0A    protected void onPause() %7B%0A        super.onPause();%0A        cancellationSignal.cancel
 ();%0A
@@ -2793,92 +2793,409 @@
     
-private void authenticate() %7B%0A        fingerprintManager.authenticate(null, 0, null,
+@NonNull%0A    private CancellationSignal authenticate() %7B%0A        CancellationSignal cancellationSignal = new CancellationSignal();%0A        fingerprintManager.authenticate(null, 0, cancellationSignal, createAuthenticationCallback(), null);%0A        return cancellationSignal;%0A    %7D%0A%0A    @NonNull%0A    private FingerprintManagerCompat.AuthenticationCallback createAuthenticationCallback() %7B%0A        return
  new
@@ -4227,32 +4227,32 @@
 ;%0A            %7D%0A
+
         %7D, null)
@@ -4244,23 +4244,16 @@
        %7D
-, null)
 ;%0A    %7D%0A

Fix FingerprintStoreActivity cancelation