package hh.dejsem;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;

import java.io.InputStream;
import java.security.KeyStore;

import hh.lib.AbendDialogFragment;
import hh.lib.D;

/**
 * Aktivita zodpovědná za dialog zadání úvodního hesla, jímž je kryt load
 * certifikátů z key store SSL-knihovny Bouncy Castle
 * <p>
 *     ● heslo se ukládá do shared prefs, takž se zadává jen po jejich výmazu
 */
public class PassW implements AbendDialogFragment.IgnoreAbend {

	public interface PasswListener { void onPasswReady(int result); }

	final static String PW_KEY = "PW_KEY";

	final static int NUM_OF_TRIES = 3;

	final static int PW_OK = 0;
	final static int PW_IGN = 1;    // passwd ignored by user
	final static int PW_BAD = 2;

	static PassW instance = null;

	public static boolean isReady() { return K.word.length() > 0; }

	public static void clearPW() {
		Prefs.sp.edit().remove(PW_KEY).apply();
		K.word = "";
		K.netNode = null;
	}

	D d;
	PasswListener subscriber;
	Context c;
	FragmentManager fm;
	GetPwDialog dialog = null;
	int totry = NUM_OF_TRIES;

	@Override
	public void ignoreAbend(boolean ignore) {
		if(ignore) subscriber.onPasswReady(PW_IGN); }

	PassW(D d, AppCompatActivity a, PasswListener subscriber) {
		this.d = d.klon(this);
		d.l(4, "readyPW");
		fm = a.getSupportFragmentManager();
		if(fm.findFragmentByTag(GetPwDialog.TAG) == null) {
			this.subscriber = subscriber;
			instance = this;
			c = a;
			checkPW();
		}
	}

	void savePW(String word) {
		if(word.equals("IGNORE")) {
			totry = 0;      // dál nezkoušet
			Prefs.sp.edit().putString(PW_KEY, "").apply();
			subscriber.onPasswReady(PW_IGN);
		}
		else {
			Prefs.sp.edit().putString(PW_KEY, word).apply();
			checkPW();
		}
	}

	void checkPW() {
		d.l(4, String.format("passwd check..."));
		try {
			final String word = Prefs.sp.getString(PW_KEY, "BAD");
			final Resources r = c.getResources();
			String ksName = String.format("bks%02d", Integer.valueOf(r.getString(R.string.channel)));
			int ksId = r.getIdentifier(ksName, "raw", c.getPackageName());
			try {
				final KeyStore ks = KeyStore.getInstance("bks");
				InputStream kfs = r.openRawResource(ksId);
				ks.load(kfs, word.toCharArray());
			}
			catch(Resources.NotFoundException e) {
				d.abendMsg(String.format("cipher keys for channel %02d not found in key store res/raw",
						Integer.valueOf(r.getString(R.string.channel))), e);
				subscriber.onPasswReady(PW_BAD);
				return;
			}
			if(word.length() == 0) throw new Exception("KeyStore integrity check failed.");
			K.word = word;
			d.l(4, String.format("passwd OK"));
			subscriber.onPasswReady(PW_OK);
		}
		catch(Exception e) {
			if(e.getMessage().equals("KeyStore integrity check failed.") && totry-- > 0) {
				new GetPwDialog().dialog(this, fm);
			}
			else d.abendMsg("passwd check", e, this);
		}
	}

	void onPW(String word) { savePW(word);}

	public static class GetPwDialog extends DialogFragment
			implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {

		static final String TAG = "password dialog";

		D d;
		PassW caller;
		EditText editText;
		AlertDialog ad = null;

		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			super.onCreateDialog(savedInstanceState);
			if(ad != null) return ad;
			setRetainInstance(true);
			final LinearLayout llv = (LinearLayout) LayoutInflater.from(getActivity()).inflate(R.layout.word_dialog, null);
			editText = (EditText)llv.findViewById(R.id.enter_text);
			final CheckBox vis = (CheckBox)llv.findViewById(R.id.visible);
			editText.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
			View.OnClickListener visCheck = new View.OnClickListener() { @Override public void onClick(View v) {
				if(vis.isChecked()) editText.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_NORMAL);
				else editText.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD); } };
			vis.setOnClickListener(visCheck);
			vis.setChecked(false);
			ad = new AlertDialog.Builder(d.getContext())
					.setView(llv)
					.setTitle("enter SSL keystore password")
					.setPositiveButton("OK", this)
					.setNegativeButton("Cancel", this)
					.create();
			return ad;
		}

		@Override
		public void onClick(DialogInterface dialog, int which) {
			if(which == DialogInterface.BUTTON_POSITIVE)
				caller.onPW(editText.getText().toString());
//				PassW.instance.savePW(editText.getText().toString());
			else
				caller.onPW("IGNORE");
//				PassW.instance.savePW("IGNORE");
			caller = null;  // aby se volal jen jednou
			dismiss();
		}

		@Override
		public void onDismiss(DialogInterface dialog) {
			if(caller != null) caller.onPW("IGNORE");
		}

		@Override
		public void onDestroyView() {
			Dialog dialog = getDialog();
			// Work around bug: http://code.google.com/p/android/issues/detail?id=17423
			if ((dialog != null) && getRetainInstance()) dialog.setDismissMessage(null);
			super.onDestroyView();
		}

		void dialog(PassW caller, FragmentManager fm) {
			this.caller = caller;
			d = caller.d.klon(this);
			show(fm, TAG);
		}
	}
}
