/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.trellisldp.spi;

import static java.util.Arrays.asList;
import static org.trellisldp.vocabulary.RDF.type;
import static org.trellisldp.vocabulary.Trellis.PreferAudit;

import java.util.ServiceLoader;
import java.util.List;

import org.apache.commons.rdf.api.BlankNodeOrIRI;
import org.apache.commons.rdf.api.Dataset;
import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDF;

import org.trellisldp.vocabulary.AS;
import org.trellisldp.vocabulary.PROV;
import org.trellisldp.vocabulary.XSD;

/**
 * The RDFUtils class provides a set of convenience methods related to
 * generating and processing RDF objects.
 *
 * @author acoburn
 */
public final class RDFUtils {

    private static RDF rdf = ServiceLoader.load(RDF.class).iterator().next();

    /**
     * Get the Commons RDF instance in use
     * @return the RDF instance
     */
    public static RDF getInstance() {
        return rdf;
    }

    /**
     * Create audit-related creation data
     * @param subject the subject
     * @param session the session
     * @return the quads
     */
    public static Dataset auditCreation(final BlankNodeOrIRI subject, final Session session) {
        return auditData(subject, session, asList(PROV.Activity, AS.Create));
    }

    /**
     * Create audit-related deletion data
     * @param subject the subject
     * @param session the session
     * @return the quads
     */
    public static Dataset auditDeletion(final BlankNodeOrIRI subject, final Session session) {
        return auditData(subject, session, asList(PROV.Activity, AS.Delete));
    }

    /**
     * Create audit-related update data
     * @param subject the subject
     * @param session the session
     * @return the quads
     */
    public static Dataset auditUpdate(final BlankNodeOrIRI subject, final Session session) {
        return auditData(subject, session, asList(PROV.Activity, AS.Update));
    }

    private static Dataset auditData(final BlankNodeOrIRI subject, final Session session, final List<IRI> types) {
        final Dataset dataset = rdf.createDataset();
        types.forEach(t ->
            dataset.add(rdf.createQuad(PreferAudit, subject, type, t)));
        dataset.add(rdf.createQuad(PreferAudit, subject, PROV.wasAssociatedWith, session.getAgent()));
        dataset.add(rdf.createQuad(PreferAudit, subject, PROV.startedAtTime,
                    rdf.createLiteral(session.getCreated().toString(), XSD.dateTime)));
        session.getDelegatedBy().ifPresent(delegate ->
                dataset.add(rdf.createQuad(PreferAudit, subject, PROV.actedOnBehalfOf, delegate)));
        return dataset;
    }

    private RDFUtils() {
        // prevent instantiation
    }
}

@@ -834,21 +834,16 @@
 lankNode
-OrIRI
 ;%0Aimport
@@ -1675,35 +1675,24 @@
 ation(final 
-BlankNodeOr
 IRI subject,
@@ -1995,35 +1995,24 @@
 etion(final 
-BlankNodeOr
 IRI subject,
@@ -2311,35 +2311,24 @@
 pdate(final 
-BlankNodeOr
 IRI subject,
@@ -2485,19 +2485,8 @@
 nal 
-BlankNodeOr
 IRI 
@@ -2595,16 +2595,158 @@
 aset();%0A
+        final BlankNode bnode = rdf.createBlankNode();%0A        dataset.add(rdf.createQuad(PreferAudit, subject, PROV.wasGeneratedBy, bnode));%0A
         
@@ -2816,23 +2816,21 @@
 rAudit, 
-subject
+bnode
 , type, 
@@ -2875,39 +2875,37 @@
 ad(PreferAudit, 
-subject
+bnode
 , PROV.wasAssoci
@@ -2980,31 +2980,29 @@
 referAudit, 
-subject
+bnode
 , PROV.start
@@ -3206,31 +3206,29 @@
 referAudit, 
-subject
+bnode
 , PROV.acted

Consolidate audit functions