package cy.agorise.crystalwallet.activities;

import android.app.PendingIntent;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener;

import org.apache.commons.codec.binary.Base32;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.util.yubikey.Algorithm;
import cy.agorise.crystalwallet.util.yubikey.OathType;
import cy.agorise.crystalwallet.util.yubikey.TOTP;
import cy.agorise.crystalwallet.util.yubikey.YkOathApi;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;

public class PocketRequestActivity extends AppCompatActivity {

    private NfcAdapter mNfcAdapter;
    private PendingIntent pendingIntent;
    private IntentFilter ndef;
    IntentFilter[] intentFiltersArray;
    String[][] techList;

    @Override
    public void onBackPressed() {
        //Do nothing to prevent the user to use the back button
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pocket_request);
        ButterKnife.bind(this);

        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

        this.configureForegroundDispatch();
    }

    public void configureForegroundDispatch(){
        if (mNfcAdapter != null) {
            pendingIntent = PendingIntent.getActivity(
                    this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

            ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
            try {
                ndef.addDataType("*/*");    /* Handles all MIME based dispatches.
                                       You should specify only the ones that you need. */
            } catch (IntentFilter.MalformedMimeTypeException e) {
                throw new RuntimeException("fail", e);
            }
            intentFiltersArray = new IntentFilter[]{ndef,};
            techList = new String[][]{ new String[] {IsoDep.class.getName(), NfcA.class.getName(), MifareClassic.class.getName(), NdefFormatable.class.getName()} };

        } else {
            Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
        }
    }

    public void onPause() {
        super.onPause();
        if (mNfcAdapter != null) {
            mNfcAdapter.disableForegroundDispatch(this);
        }
    }

    public void onResume() {
        super.onResume();
        if (mNfcAdapter != null) {
            mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techList);
        }
    }

    public void onNewIntent(Intent intent) {
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        IsoDep tagIsoDep = IsoDep.get(tagFromIntent);
        Log.i("Tag from nfc","New Intent");
        String yubikeySecret = CrystalSecurityMonitor.getInstance(null).get2ndFactorValue();

        try {
            tagIsoDep.connect();
            YkOathApi ykOathApi = new YkOathApi(tagIsoDep);

            long unixTime = System.currentTimeMillis() / 1000L;
            byte[] timeStep = ByteBuffer.allocate(8).putLong(unixTime / 30L).array();
            byte[] response;
            response = ykOathApi.calculate("cy.agorise.crystalwallet",timeStep,true);
            ByteBuffer responseBB = ByteBuffer.wrap(response);
            int digits = (int)responseBB.get();
            String challengeString = ""+(responseBB.getInt());
            String challenge = challengeString.substring(challengeString.length()-digits);
            while (challenge.length() < digits){
                challenge = '0'+challenge;
            }

            String storedChallenge = PasswordManager.totpd(yubikeySecret, unixTime, ykOathApi.getDeviceSalt());

            Toast.makeText(this, "Secret:"+yubikeySecret+" StoredChallenge:"+storedChallenge+" Yubikey:"+challenge , Toast.LENGTH_LONG).show();

            Log.i("TOTP","Secret: "+yubikeySecret);
            Log.i("TOTP", "Unixtime: "+unixTime);
            Log.i("TOTP", "Step: "+unixTime/30L);
            Log.i("TOTP", "StoredChallenge: "+storedChallenge);
            Log.i("TOTP", "Yubikey: "+challenge);

            tagIsoDep.close();
            //ykOathApi.
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}


