package org.mercury_im.messenger.data.repository;

import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.jivesoftware.smackx.ikey.record.IkeyRecord;
import org.jivesoftware.smackx.ikey.record.OxSubordinateRecord;
import org.junit.jupiter.api.Test;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.data.di.component.DaggerInMemoryDatabaseComponent;
import org.mercury_im.messenger.data.di.component.InMemoryDatabaseComponent;
import org.pgpainless.PGPainless;
import org.pgpainless.key.OpenPgpV4Fingerprint;

import java.net.URI;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.UUID;

import javax.inject.Inject;

import io.requery.Persistable;
import io.requery.reactivex.ReactiveEntityStore;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class IkeyRepositoryTest {

    @Inject
    ReactiveEntityStore<Persistable> dataStore;

    @Inject
    RxIkeyRepository ikeyRepository;

    @Inject
    public IkeyRepositoryTest() {
        InMemoryDatabaseComponent testComponent = DaggerInMemoryDatabaseComponent.builder()
                .build();
        testComponent.inject(this);
    }

    @Test
    public void test() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
        UUID accountId = UUID.randomUUID();
        EntityBareJid jid = JidCreate.entityBareFromOrThrowUnchecked("test@test.test");
        PGPPublicKeyRing publicKey = PGPainless.generateKeyRing().simpleEcKeyRing(jid.asEntityBareJidString()).getPublicKeys();
        Date date = new Date();

        IkeyRecord firstRecord = new IkeyRecord();
        firstRecord.setSuperordinate(publicKey);
        firstRecord.setTimestamp(date);
        firstRecord.setJid(jid);

        OxSubordinateRecord firstSub = new OxSubordinateRecord();
        firstSub.setUri(URI.create("xmpp.pubsub:pubsub.shakespeare.lit"));
        firstSub.setOxFingerprint(new OpenPgpV4Fingerprint("1357B01865B2503C18453D208CAC2A9678548E35"));
        firstRecord.getSubordinates().add(firstSub);

        ikeyRepository.storeRecord(accountId, jid, firstRecord)
                .blockingAwait();
        IkeyRecord loaded = ikeyRepository.loadRecord(accountId, jid).blockingFirst();
        assertEquals(1, loaded.getSubordinates().size());
        assertEquals(firstSub, loaded.getSubordinates().get(0));


        IkeyRecord secondRecord = new IkeyRecord();
        secondRecord.setJid(jid);
        secondRecord.setTimestamp(new Date());
        secondRecord.setSuperordinate(publicKey);

        OxSubordinateRecord secondSub = new OxSubordinateRecord();
        secondSub.setOxFingerprint(new OpenPgpV4Fingerprint("1357B01865B2503C18453D208CAC2A9678448E15"));
        secondSub.setUri(URI.create("xmpp.pubsub:pubsub.shakespeare.lot"));
        secondRecord.getSubordinates().add(secondSub);

        ikeyRepository.storeRecord(accountId, jid, secondRecord)
                .blockingAwait();
        IkeyRecord loaded1 = ikeyRepository.loadRecord(accountId, jid).blockingFirst();
        assertEquals(1, loaded1.getSubordinates().size(), "Second record must only contain one subordinate.");
        assertEquals(secondSub, loaded1.getSubordinates().get(0));
    }
}
