// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintEncryptionResult.java
// public class FingerprintEncryptionResult extends FingerprintAuthenticationResult {
// 
//     private final String encrypted;
// 
//     /**
//      * Default constructor
//      *
//      * @param result    result of the operation
//      * @param message   message to be displayed to the user
//      * @param encrypted encrypted data
//      */
//     public FingerprintEncryptionResult(FingerprintResult result, String message, String encrypted) {
//         super(result, message);
//         this.encrypted = encrypted;
//     }
// 
//     /**
//      * @return encrypted data, can only be accessed if the result was of
//      * type {@link FingerprintResult#AUTHENTICATED}
//      */
//     public String getEncrypted() {
//         if (!isSuccess()) {
//             throw new IllegalAccessError("Fingerprint authentication was not successful, cannot access encryption result");
//         }
//         return encrypted;
//     }
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintResult.java
// public enum FingerprintResult {
//     FAILED, HELP, AUTHENTICATED
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintUnavailableException.java
// public class FingerprintUnavailableException extends Exception {
// 
// 	public FingerprintUnavailableException(String s) {
// 		super(s);
// 	}
// }


import android.content.Context;
import android.support.annotation.VisibleForTesting;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import com.mtramin.rxfingerprint.data.FingerprintResult;
import com.mtramin.rxfingerprint.data.FingerprintUnavailableException;
import javax.crypto.Cipher;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
	 * @param toEncrypt data to encrypt  @return Observable {@link FingerprintEncryptionResult}
	 */
	static Observable<FingerprintEncryptionResult> create(Context context, String keyName, char[] toEncrypt, boolean keyInvalidatedByBiometricEnrollment) {
		if (toEncrypt == null) {
			return Observable.error(new IllegalArgumentException("String to be encrypted is null. Can only encrypt valid strings"));
		}
		try {
			return Observable.create(new RsaEncryptionObservable(new FingerprintApiWrapper(context),
					new RsaCipherProvider(context, keyName, keyInvalidatedByBiometricEnrollment),
					toEncrypt,
					new Base64Provider()));
		} catch (Exception e) {
			return Observable.error(e);
		}
	}

	@VisibleForTesting
	RsaEncryptionObservable(FingerprintApiWrapper fingerprintApiWrapper,
							RsaCipherProvider cipherProvider,
							char[] toEncrypt,
							EncodingProvider encodingProvider) {
		this.fingerprintApiWrapper = fingerprintApiWrapper;
		this.cipherProvider = cipherProvider;
		this.toEncrypt = toEncrypt;
		this.encodingProvider = encodingProvider;
	}

	@Override
	public void subscribe(ObservableEmitter<FingerprintEncryptionResult> emitter) throws Exception {
		if (fingerprintApiWrapper.isUnavailable()) {
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintEncryptionResult.java
// public class FingerprintEncryptionResult extends FingerprintAuthenticationResult {
// 
//     private final String encrypted;
// 
//     /**
//      * Default constructor
//      *
//      * @param result    result of the operation
//      * @param message   message to be displayed to the user
//      * @param encrypted encrypted data
//      */
//     public FingerprintEncryptionResult(FingerprintResult result, String message, String encrypted) {
//         super(result, message);
//         this.encrypted = encrypted;
//     }
// 
//     /**
//      * @return encrypted data, can only be accessed if the result was of
//      * type {@link FingerprintResult#AUTHENTICATED}
//      */
//     public String getEncrypted() {
//         if (!isSuccess()) {
//             throw new IllegalAccessError("Fingerprint authentication was not successful, cannot access encryption result");
//         }
//         return encrypted;
//     }
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintResult.java
// public enum FingerprintResult {
//     FAILED, HELP, AUTHENTICATED
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintUnavailableException.java
// public class FingerprintUnavailableException extends Exception {
// 
// 	public FingerprintUnavailableException(String s) {
// 		super(s);
// 	}
// }


// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/RsaEncryptionObservable.java
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import com.mtramin.rxfingerprint.data.FingerprintResult;
import com.mtramin.rxfingerprint.data.FingerprintUnavailableException;
import javax.crypto.Cipher;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;

	 * @param toEncrypt data to encrypt  @return Observable {@link FingerprintEncryptionResult}
	 */
	static Observable<FingerprintEncryptionResult> create(Context context, String keyName, char[] toEncrypt, boolean keyInvalidatedByBiometricEnrollment) {
		if (toEncrypt == null) {
			return Observable.error(new IllegalArgumentException("String to be encrypted is null. Can only encrypt valid strings"));
		}
		try {
			return Observable.create(new RsaEncryptionObservable(new FingerprintApiWrapper(context),
					new RsaCipherProvider(context, keyName, keyInvalidatedByBiometricEnrollment),
					toEncrypt,
					new Base64Provider()));
		} catch (Exception e) {
			return Observable.error(e);
		}
	}

	@VisibleForTesting
	RsaEncryptionObservable(FingerprintApiWrapper fingerprintApiWrapper,
							RsaCipherProvider cipherProvider,
							char[] toEncrypt,
							EncodingProvider encodingProvider) {
		this.fingerprintApiWrapper = fingerprintApiWrapper;
		this.cipherProvider = cipherProvider;
		this.toEncrypt = toEncrypt;
		this.encodingProvider = encodingProvider;
	}

	@Override
	public void subscribe(ObservableEmitter<FingerprintEncryptionResult> emitter) throws Exception {
		if (fingerprintApiWrapper.isUnavailable()) {
			emitter.onError(new FingerprintUnavailableException("Fingerprint authentication is not available on this device! Ensure that the device has a Fingerprint sensor and enrolled Fingerprints by calling RxFingerprint#isAvailable(Context) first"));