package org.mercury_im.messenger.android.ui.account.login;

import android.app.Application;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import org.bouncycastle.openpgp.PGPException;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
import org.jivesoftware.smackx.ox.element.SecretkeyElement;
import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException;
import org.mercury_im.messenger.android.MercuryImApplication;
import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.core.viewmodel.ikey.IkeySetupViewModel;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.UUID;

import javax.inject.Inject;

import io.reactivex.Single;

public class AndroidIkeySetupViewModel extends AndroidViewModel implements MercuryAndroidViewModel<IkeySetupViewModel> {

    @Inject
    IkeySetupViewModel commonViewModel;

    private MutableLiveData<Optional<String>> passphraseError = new MutableLiveData<>();

    public AndroidIkeySetupViewModel(@NonNull Application application) {
        super(application);
        MercuryImApplication.getApplication().getAppComponent().inject(this);
    }

    public void init(UUID accountId) {
        getCommonViewModel().init(accountId);
    }

    public Single<Optional<SecretkeyElement>> fetchBackupElement() {
        return getCommonViewModel().fetchBackupElement();
    }

    @Override
    public IkeySetupViewModel getCommonViewModel() {
        return commonViewModel;
    }

    public void generateIdentityKey() throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
        getCommonViewModel().generateIdentityKey();
    }

    public boolean restoreBackup(String backupCode) {
        OpenPgpSecretKeyBackupPassphrase passphrase;
        try {
            passphrase = new OpenPgpSecretKeyBackupPassphrase(backupCode);
        } catch (IllegalArgumentException e) {
            passphraseError.setValue(new Optional<>("Malformed Passphrase"));
            return false;
        }

        try {
            getCommonViewModel().restoreBackup(passphrase);
            passphraseError.setValue(new Optional<>());
            return true;
        } catch (InvalidBackupCodeException e) {
            passphraseError.setValue(new Optional<>("Wrong Passphrase"));
        } catch (IOException | PGPException e) {
            passphraseError.setValue(new Optional<>("Error: " + e.getMessage()));
        }
        return false;
    }

    public LiveData<Optional<String>> getPassphraseError() {
        return passphraseError;
    }
}
