<commit_before>package won.protocol.agreement;

import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.jena.query.Dataset;
import org.apache.jena.query.DatasetFactory;
import org.apache.jena.query.ReadWrite;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.NodeIterator;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.ResIterator;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.rdf.model.impl.ResourceImpl;
import org.apache.jena.rdf.model.impl.StatementImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import won.protocol.agreement.effect.MessageEffect;
import won.protocol.agreement.effect.MessageEffectsBuilder;
import won.protocol.agreement.effect.ProposalType;
import won.protocol.message.WonMessageDirection;
import won.protocol.message.WonMessageType;
import won.protocol.util.RdfUtils;
import won.protocol.util.WonRdfUtils;
import won.protocol.util.linkeddata.LinkedDataSource;
import won.protocol.util.linkeddata.WonLinkedDataUtils;
import won.protocol.vocabulary.WONAGR;

public class AgreementProtocolState {
    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    private final Dataset pendingProposals = DatasetFactory.createGeneral();
    private final Dataset agreements = DatasetFactory.createGeneral();
    private final Dataset claims = DatasetFactory.createGeneral();
    private final Dataset cancelledAgreements = DatasetFactory.createGeneral();
    private final Dataset rejected = DatasetFactory.createGeneral();
    private Dataset conversation = null;
    private final Set<URI> retractedUris = new HashSet<URI>(); // TODO: Check!
    private final Set<URI> claimedUris = new HashSet<URI>();
    private final Set<URI> acceptedCancellationProposalUris = new HashSet<URI>();
    private Map<URI, ConversationMessage> messagesByURI = new HashMap<>();
    private Set<DeliveryChain> deliveryChains = new HashSet<>();

    public static AgreementProtocolState of(URI connectionURI, LinkedDataSource linkedDataSource) {
        Dataset fullConversationDataset = WonLinkedDataUtils.getConversationAndAtomsDataset(connectionURI,
                        linkedDataSource);
        return AgreementProtocolState.of(fullConversationDataset);
    }

    public static AgreementProtocolState of(Dataset conversation) {
        AgreementProtocolState instance = new AgreementProtocolState();
        instance.recalculate(conversation);
        return instance;
    }

    private AgreementProtocolState() {
    }

    public AgreementProtocolUris getAgreementProtocolUris() {
        AgreementProtocolUris uris = new AgreementProtocolUris();
        uris.addAgreementUris(getAgreementUris());
        uris.addAcceptedUris(getAgreedMessageUris());
        uris.addAcceptedCancellationProposalUris(getAcceptedCancellationProposalUris());
        uris.addCancelledAgreementUris(getCancelledAreementUris());
        // walk over pending proposals and collect the relevant uris:
        messagesByURI.values().stream().filter(m -> isPendingProposal(m.getMessageURI())).forEach(m -> {
            // so this is a pending proposal.
            // determine what it would cancel
            Set<URI> cancelled = m.getEffects().stream().filter(e -> e.isProposes()).map(e -> e.asProposes())
                            .flatMap(e -> e.getProposesToCancel().stream()).filter(this::isAgreement)
                            .collect(Collectors.toSet());
            uris.addCancellationPendingAgreementUris(cancelled);
            // determine what it proposes
            Set<URI> proposed = m.getEffects().stream().filter(e -> e.isProposes()).map(e -> e.asProposes())
                            .flatMap(e -> e.getProposes().stream()).collect(Collectors.toSet());
            boolean isProposal = false;
            if (!cancelled.isEmpty()) {
                // remember this is a pending proposal that would cancel stuff
                // uris.addPendingCancellationProposalUri(m.getMessageURI());
                isProposal = true;
            }
            if (!proposed.isEmpty()) {
                // remember this is a pending proposal that proposes stuff
                uris.addPendingProposalUri(m.getMessageURI());
                isProposal = true;
            }
            if (isProposal) {
                // this proposal is not empty - add it to the pending proposals
                ProposalUris proposal = new ProposalUris(m.getMessageURI(), m.getSenderAtomURI());
                proposal.addProposes(proposed);
                proposal.addProposesToCancel(cancelled);
                uris.addPendingProposal(proposal);
            }
        });

        uris.addPendingCancellationProposalUris(getCancellationPendingAgreementUris());
        uris.addClaimedMessageUris(getClaimedUris());
        uris.addRejectedMessageUris(getRejectedUris());
        uris.addRetractedMessageUris(getRetractedUris());
        return uris;
    }

    public Dataset getConversationDataset() {
        return this.conversation;
    }

    /**<commit_msg>Fix format<commit_after>package won.protocol.agreement;

import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.jena.query.Dataset;
import org.apache.jena.query.DatasetFactory;
import org.apache.jena.query.ReadWrite;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.NodeIterator;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.ResIterator;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.rdf.model.impl.ResourceImpl;
import org.apache.jena.rdf.model.impl.StatementImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import won.protocol.agreement.effect.MessageEffect;
import won.protocol.agreement.effect.MessageEffectsBuilder;
import won.protocol.agreement.effect.ProposalType;
import won.protocol.message.WonMessageDirection;
import won.protocol.message.WonMessageType;
import won.protocol.util.RdfUtils;
import won.protocol.util.WonRdfUtils;
import won.protocol.util.linkeddata.LinkedDataSource;
import won.protocol.util.linkeddata.WonLinkedDataUtils;
import won.protocol.vocabulary.WONAGR;

public class AgreementProtocolState {
    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    private final Dataset pendingProposals = DatasetFactory.createGeneral();
    private final Dataset agreements = DatasetFactory.createGeneral();
    private final Dataset claims = DatasetFactory.createGeneral();
    private final Dataset cancelledAgreements = DatasetFactory.createGeneral();
    private final Dataset rejected = DatasetFactory.createGeneral();
    private Dataset conversation = null;
    private final Set<URI> retractedUris = new HashSet<URI>(); // TODO: Check!
    private final Set<URI> claimedUris = new HashSet<URI>();
    private final Set<URI> acceptedCancellationProposalUris = new HashSet<URI>();
    private Map<URI, ConversationMessage> messagesByURI = new HashMap<>();
    private Set<DeliveryChain> deliveryChains = new HashSet<>();

    public static AgreementProtocolState of(URI connectionURI, LinkedDataSource linkedDataSource) {
        Dataset fullConversationDataset = WonLinkedDataUtils.getConversationAndAtomsDataset(connectionURI,
                        linkedDataSource);
        return AgreementProtocolState.of(fullConversationDataset);
    }

    public static AgreementProtocolState of(Dataset conversation) {
        AgreementProtocolState instance = new AgreementProtocolState();
        instance.recalculate(conversation);
        return instance;
    }

    private AgreementProtocolState() {
    }

    public AgreementProtocolUris getAgreementProtocolUris() {
        AgreementProtocolUris uris = new AgreementProtocolUris();
        uris.addAgreementUris(getAgreementUris());
        uris.addAcceptedUris(getAgreedMessageUris());
        uris.addAcceptedCancellationProposalUris(getAcceptedCancellationProposalUris());
        uris.addCancelledAgreementUris(getCancelledAreementUris());
        // walk over pending proposals and collect the relevant uris:
        messagesByURI.values().stream().filter(m -> isPendingProposal(m.getMessageURI())).forEach(m -> {
            // so this is a pending proposal.
            // determine what it would cancel
            Set<URI> cancelled = m.getEffects().stream().filter(e -> e.isProposes()).map(e -> e.asProposes())
                            .flatMap(e -> e.getProposesToCancel().stream()).filter(this::isAgreement)
                            .collect(Collectors.toSet());
            uris.addCancellationPendingAgreementUris(cancelled);
            // determine what it proposes
            Set<URI> proposed = m.getEffects().stream().filter(e -> e.isProposes()).map(e -> e.asProposes())
                            .flatMap(e -> e.getProposes().stream()).collect(Collectors.toSet());
            boolean isProposal = false;
            if (!cancelled.isEmpty()) {
                // remember this is a pending proposal that would cancel stuff
                // uris.addPendingCancellationProposalUri(m.getMessageURI());
                isProposal = true;
            }
            if (!proposed.isEmpty()) {
                // remember this is a pending proposal that proposes stuff
                uris.addPendingProposalUri(m.getMessageURI());
                isProposal = true;
            }
            if (isProposal) {
                // this proposal is not empty - add it to the pending proposals
                ProposalUris proposal = new ProposalUris(m.getMessageURI(), m.getSenderAtomURI());
                proposal.addProposes(proposed);
                proposal.addProposesToCancel(cancelled);
                uris.addPendingProposal(proposal);
            }
        });
        uris.addPendingCancellationProposalUris(getCancellationPendingAgreementUris());
        uris.addClaimedMessageUris(getClaimedUris());
        uris.addRejectedMessageUris(getRejectedUris());
        uris.addRetractedMessageUris(getRetractedUris());
        return uris;
    }

    public Dataset getConversationDataset() {
        return this.conversation;
    }

    /**
{'fraction_non_alphanumeric': 0.09998208206414622, 'fraction_numerical': 0.00035835871707579287, 'mean_word_length': 3.403550295857988, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5156104', 'n_tokens_mistral': 3083, 'n_tokens_neox': 3059, 'n_words': 587}