/*
 *  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.
 *
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership.
 */

package org.apache.jena.dboe.storage.system;

import java.util.Iterator;

import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.dboe.storage.DatabaseRDF;
import org.apache.jena.dboe.storage.StoragePrefixes;
import org.apache.jena.dboe.storage.StorageRDF;
import org.apache.jena.dboe.transaction.txn.IteratorTxnTracker;
import org.apache.jena.dboe.transaction.txn.TransactionalSystem;
import org.apache.jena.dboe.transaction.txn.TxnId;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.ReadWrite;
import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.core.*;

/** Alternative: DatasetGraph over RDFStorage, using DatasetGraphBaseFind
 *  Collapses DatasetGraphTriplesQuads into this adapter class.
<pre>
DatasetGraph
  DatasetGraphBase
    DatasetGraphBaseFind
      DatasetGraphStorageDirect
</pre>
/**
 * A DatasetGraph base class for triples+quads storage. The machinery is really
 * the splitting between default and named graphs. This happens in two classes,
 * {@link DatasetGraphBaseFind} (for find splitting) and
 * {@link DatasetGraphTriplesQuads} add/delete splitting (it inherits
 * {@link DatasetGraphBaseFind}).
 * <p>
 * Because storage is usually decomposing quads and triples, the default
 * behaviour is to work in s/p/o and g/s/p/o.
 */

public class DatasetGraphStorage extends DatasetGraphBaseFind implements DatabaseRDF
{
    private final Transactional txn;
    @Override public void begin()                       { txn.begin(); }
    @Override public void begin(TxnType txnType)        { txn.begin(txnType); }
    @Override public void begin(ReadWrite mode)         { txn.begin(mode); }
    @Override public boolean promote(Promote mode)      { return txn.promote(mode); }
    @Override public void commit()                      { txn.commit(); }
    @Override public void abort()                       { txn.abort(); }
    @Override public boolean isInTransaction()          { return txn.isInTransaction(); }
    @Override public void end()                         { txn.end(); }
    @Override public ReadWrite transactionMode()        { return txn.transactionMode(); }
    @Override public TxnType transactionType()          { return txn.transactionType(); }
    @Override public boolean supportsTransactions()     { return true; }
    @Override public boolean supportsTransactionAbort() { return false; }

    private final StorageRDF storage;
    private final StoragePrefixes prefixes;

    public DatasetGraphStorage(StorageRDF storage, StoragePrefixes prefixes, Transactional transactional) {
        this.storage = storage;
        this.prefixes = prefixes;
        this.txn = transactional;
    }

    @Override public StorageRDF getData()             { return storage; }
    @Override public StoragePrefixes getPrefixes()    { return prefixes; }
    @Override public Transactional getTransactional() { return txn; }

    /**
     * Provide a general implementation of "listGraphNodes". Implementations may wish
     * to override and do this operation in a more efficient manner.
     */
    @Override
    public Iterator<Node> listGraphNodes() {
        Iterator<Quad> iter = findNG(null, null, null, null);
        return Iter.iter(iter).map(Quad::getGraph).distinct();
    }

    private <T> Iterator<T> isolate(Iterator<T> iterator) {
        if ( txn.isInTransaction() && txn instanceof TransactionalSystem) {
            // Needs TxnId to track.
            TransactionalSystem txnSystem = (TransactionalSystem)txn;
            TxnId txnId = txnSystem.getThreadTransaction().getTxnId();
            // Add transaction protection.
            return new IteratorTxnTracker<>(iterator, txnSystem, txnId);
        }
        return Iter.iterator(iterator);
    }

    private Iterator<Triple> findStorage(Node s, Node p, Node o) {
        return isolate(storage.find(s, p, o));
    }

    private Iterator<Quad> findStorage(Node g, Node s, Node p, Node o) {
        return isolate(storage.find(g, s, p, o));
    }

    @Override
    protected Iterator<Quad> findInDftGraph(Node s, Node p, Node o) {
        return Iter.map(findStorage(s, p, o), t -> Quad.create(Quad.defaultGraphIRI, t));
    }

    @Override
    protected Iterator<Quad> findInSpecificNamedGraph(Node g, Node s, Node p, Node o) {
        return findStorage(g, s, p, o);
    }

    @Override
    protected Iterator<Quad> findInAnyNamedGraphs(Node s, Node p, Node o) {
        // Implementations may wish to do better.
        return findStorage(Node.ANY, s, p, o);
    }

    @Override
    public Graph getDefaultGraph() {
        return GraphViewStorage.createDefaultGraphStorage(this, prefixes);
    }

    @Override
    public Graph getUnionGraph() {
        return GraphViewStorage.createUnionGraphStorage(this, prefixes);
    }

    @Override
    public Graph getGraph(Node graphNode) {
        return GraphViewStorage.createNamedGraphStorage(this,  graphNode, prefixes);
    }

    @Override
    public void add(Quad quad) {
        if ( Quad.isDefaultGraph(quad.getGraph()) )
            storage.add(quad.getSubject(), quad.getPredicate(), quad.getObject());
        else
            storage.add(quad);
    }

    @Override
    public void delete(Quad quad) {
        if ( Quad.isDefaultGraph(quad.getGraph()) )
            storage.delete(quad.getSubject(), quad.getPredicate(), quad.getObject());
        else
            storage.delete(quad);
    }

    @Override
    public void add(Node g, Node s, Node p, Node o) {
        if ( g == null || Quad.isDefaultGraph(g) )
            storage.add(s,p,o);
        else
            storage.add(g,s,p,o);
    }

    @Override
    public void delete(Node g, Node s, Node p, Node o) {
        if ( g == null || Quad.isDefaultGraph(g) )
            storage.delete(s,p,o);
        else
            storage.delete(g,s,p,o);
    }

    @Override
    public void addGraph(Node graphName, Graph graph) {
        graph.find(null,null,null).forEachRemaining(t->add(graphName, t.getSubject(), t.getPredicate(), t.getObject()));
    }

    @Override
    public void removeGraph(Node graphName) {
        storage.removeAll(graphName, null, null, null);
        prefixes.deleteAll(graphName);
    }
}
