/*
 * Copyright (C) 2018 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.biometrics;

import android.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.UserHandle;

import com.android.settings.core.InstrumentedFragment;
import com.android.settings.password.ChooseLockSettingsHelper;

import java.util.ArrayList;

/**
 * Abstract sidecar fragment to handle the state around biometric enrollment. This sidecar manages
 * the state of enrollment throughout the activity lifecycle so the app can continue after an
 * event like rotation.
 */
public abstract class BiometricEnrollSidecar extends InstrumentedFragment {

    public interface Listener {
        void onEnrollmentHelp(int helpMsgId, CharSequence helpString);
        void onEnrollmentError(int errMsgId, CharSequence errString);
        void onEnrollmentProgressChange(int steps, int remaining);
    }

    private int mEnrollmentSteps = -1;
    private int mEnrollmentRemaining = 0;
    private Listener mListener;
    private boolean mEnrolling;
    private Handler mHandler = new Handler();
    private boolean mDone;
    private ArrayList<QueuedEvent> mQueuedEvents;

    protected CancellationSignal mEnrollmentCancel;
    protected byte[] mToken;
    protected int mUserId;

    private abstract class QueuedEvent {
        public abstract void send(Listener listener);
    }

    private class QueuedEnrollmentProgress extends QueuedEvent {
        int enrollmentSteps;
        int remaining;
        public QueuedEnrollmentProgress(int enrollmentSteps, int remaining) {
            this.enrollmentSteps = enrollmentSteps;
            this.remaining = remaining;
        }

        @Override
        public void send(Listener listener) {
            listener.onEnrollmentProgressChange(enrollmentSteps, remaining);
        }
    }

    private class QueuedEnrollmentHelp extends QueuedEvent {
        int helpMsgId;
        CharSequence helpString;
        public QueuedEnrollmentHelp(int helpMsgId, CharSequence helpString) {
            this.helpMsgId = helpMsgId;
            this.helpString = helpString;
        }

        @Override
        public void send(Listener listener) {
            listener.onEnrollmentHelp(helpMsgId, helpString);
        }
    }

    private class QueuedEnrollmentError extends QueuedEvent {
        int errMsgId;
        CharSequence errString;
        public QueuedEnrollmentError(int errMsgId, CharSequence errString) {
            this.errMsgId = errMsgId;
            this.errString = errString;
        }

        @Override
        public void send(Listener listener) {
            listener.onEnrollmentError(errMsgId, errString);
        }
    }

    private final Runnable mTimeoutRunnable = new Runnable() {
        @Override
        public void run() {
            cancelEnrollment();
        }
    };

    public BiometricEnrollSidecar() {
        mQueuedEvents = new ArrayList<>();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mToken = activity.getIntent().getByteArrayExtra(
                ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
        mUserId = activity.getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
    }

    @Override
    public void onStart() {
        super.onStart();
        if (!mEnrolling) {
            startEnrollment();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (!getActivity().isChangingConfigurations()) {
            cancelEnrollment();
        }
    }

    protected void startEnrollment() {
        mHandler.removeCallbacks(mTimeoutRunnable);
        mEnrollmentSteps = -1;
        mEnrollmentCancel = new CancellationSignal();
        mEnrolling = true;
    }

    public boolean cancelEnrollment() {
        mHandler.removeCallbacks(mTimeoutRunnable);
        if (mEnrolling) {
            mEnrollmentCancel.cancel();
            mEnrolling = false;
            mEnrollmentSteps = -1;
            return true;
        }
        return false;
    }

    protected void onEnrollmentProgress(int remaining) {
        if (mEnrollmentSteps == -1) {
            mEnrollmentSteps = remaining;
        }
        mEnrollmentRemaining = remaining;
        mDone = remaining == 0;
        if (mListener != null) {
            mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining);
        } else {
            mQueuedEvents.add(new QueuedEnrollmentProgress(mEnrollmentSteps, remaining));
        }
    }

    protected void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
        if (mListener != null) {
            mListener.onEnrollmentHelp(helpMsgId, helpString);
        } else {
            mQueuedEvents.add(new QueuedEnrollmentHelp(helpMsgId, helpString));
        }
    }

    protected void onEnrollmentError(int errMsgId, CharSequence errString) {
        if (mListener != null) {
            mListener.onEnrollmentError(errMsgId, errString);
        } else {
            mQueuedEvents.add(new QueuedEnrollmentError(errMsgId, errString));
        }
        mEnrolling = false;
    }

    public void setListener(Listener listener) {
        mListener = listener;
        if (mListener != null) {
            for (int i=0; i<mQueuedEvents.size(); i++) {
                QueuedEvent event = mQueuedEvents.get(i);
                event.send(mListener);
            }
            mQueuedEvents.clear();
        }
    }

    public int getEnrollmentSteps() {
        return mEnrollmentSteps;
    }

    public int getEnrollmentRemaining() {
        return mEnrollmentRemaining;
    }

    public boolean isDone() {
        return mDone;
    }

    public boolean isEnrolling() {
        return mEnrolling;
    }
}
