package org.jivesoftware.smackx.ikey.util;

import org.jivesoftware.smackx.ikey.record.IkeyRecord;
import org.jivesoftware.smackx.ikey.record.IkeyStore;
import org.jivesoftware.smackx.ikey.record.IkeySubordinateRecord;
import org.jivesoftware.smackx.ikey.record.OxSubordinateRecord;
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
import org.jxmpp.jid.BareJid;
import org.pgpainless.key.OpenPgpV4Fingerprint;

import java.io.IOException;
import java.util.List;

import javax.inject.Inject;

public class IkeyOpenPgpTrustStore implements OpenPgpTrustStore {

    private final IkeyStore ikeyStore;
    private final IkeyOpenPgpTrustStore oxIkeyTrustStore;
    private final OpenPgpTrustStore oxTrustStore;

    @Inject
    public IkeyOpenPgpTrustStore(IkeyStore ikeyStore, IkeyOpenPgpTrustStore oxIkeyTrustStore, OpenPgpTrustStore oxTrustStore) {
        this.ikeyStore = ikeyStore;
        this.oxIkeyTrustStore = oxIkeyTrustStore;
        this.oxTrustStore = oxTrustStore;
    }

    @Override
    public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException {
        IkeyRecord record = ikeyStore.loadIkeyRecord(owner.asEntityBareJidOrThrow());

        if (record == null) {
            // No Ikey record -> fall back to manual trust
            return oxTrustStore.getTrust(owner, fingerprint);
        }

        List<IkeySubordinateRecord> subordinates = record.getSubordinates();
        for (IkeySubordinateRecord subordinate : subordinates) {
            if (subordinate instanceof OxSubordinateRecord) {
                OxSubordinateRecord oxSubordinate = (OxSubordinateRecord) subordinate;
                OpenPgpV4Fingerprint subordinateFingerprint = oxSubordinate.getOxFingerprint();
                if (fingerprint.equals(subordinateFingerprint)) {
                    return oxIkeyTrustStore.oxIkeyTrustStore.getTrust(owner, new OpenPgpV4Fingerprint(record.getSuperordinate()));
                }
            }
        }
        // key not included in ikey record -> fall back to manual trust
        return oxTrustStore.getTrust(owner, fingerprint);
    }

    @Override
    public void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) throws IOException {
        oxTrustStore.setTrust(owner, fingerprint, trust);
    }
}
