/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.commons.rdf.simple;

import org.apache.commons.rdf.api.*;
import org.apache.commons.rdf.simple.SimpleRDF.SimpleRDFTerm;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * A simple, memory-based implementation of Graph.
 * <p>
 * {@link Triple}s in the graph are kept in a {@link Set}.
 * <p>
 * All Stream operations are performed using parallel and unordered directives.
 */
final class GraphImpl implements Graph {

    private static final int TO_STRING_MAX = 10;
    private final Set<Triple> triples = new HashSet<>();
    private final SimpleRDF factory;

    GraphImpl(final SimpleRDF simpleRDF) {
        this.factory = simpleRDF;
    }

    @Override
    public void add(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
        final BlankNodeOrIRI newSubject = (BlankNodeOrIRI) internallyMap(subject);
        final IRI newPredicate = (IRI) internallyMap(predicate);
        final RDFTerm newObject = internallyMap(object);
        final Triple result = factory.createTriple(newSubject, newPredicate, newObject);
        triples.add(result);
    }

    @Override
    public void add(final Triple triple) {
        triples.add(internallyMap(triple));
    }

    private <T extends RDFTerm> RDFTerm internallyMap(final T object) {
        if (object == null || object instanceof SimpleRDFTerm) {
            // No need to re-map our own objects.
            // We support null as internallyMap() is also used by the filters,
            // and the
            // factory constructors later do null checks
            return object;
        }
        if (object instanceof BlankNode) {
            final BlankNode blankNode = (BlankNode) object;
            // This guarantees that adding the same BlankNode multiple times to
            // this graph will generate a local object that is mapped to an
            // equivalent object, based on the code in the package private
            // BlankNodeImpl class
            return factory.createBlankNode(blankNode.uniqueReference());
        } else if (object instanceof IRI) {
            final IRI iri = (IRI) object;
            return factory.createIRI(iri.getIRIString());
        } else if (object instanceof Literal) {
            final Literal literal = (Literal) object;
            if (literal.getLanguageTag().isPresent()) {
                return factory.createLiteral(literal.getLexicalForm(), literal.getLanguageTag().get());
            }
            return factory.createLiteral(literal.getLexicalForm(), (IRI) internallyMap(literal.getDatatype()));
        } else {
            throw new IllegalArgumentException("RDFTerm was neither a BlankNode, IRI nor Literal: " + object);
        }
    }

    private Triple internallyMap(final Triple triple) {
        final BlankNodeOrIRI newSubject = (BlankNodeOrIRI) internallyMap(triple.getSubject());
        final IRI newPredicate = (IRI) internallyMap(triple.getPredicate());
        final RDFTerm newObject = internallyMap(triple.getObject());
        // Check if any of the object references changed during the mapping, to
        // avoid creating a new Triple object if possible
        if (newSubject == triple.getSubject() && newPredicate == triple.getPredicate()
                && newObject == triple.getObject()) {
            return triple;
        }
        return factory.createTriple(newSubject, newPredicate, newObject);
    }

    @Override
    public void clear() {
        triples.clear();
    }

    @Override
    public boolean contains(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
        return stream(subject, predicate, object).findFirst().isPresent();
    }

    @Override
    public boolean contains(final Triple triple) {
        return triples.contains(internallyMap(triple));
    }

    @Override
    public Stream<Triple> stream() {
        return triples.parallelStream().unordered();
    }

    @Override
    public Stream<Triple> stream(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
        final BlankNodeOrIRI newSubject = (BlankNodeOrIRI) internallyMap(subject);
        final IRI newPredicate = (IRI) internallyMap(predicate);
        final RDFTerm newObject = internallyMap(object);

        return getTriples(t -> {
            // Lacking the requirement for .equals() we have to be silly
            // and test ntriples string equivalance
            if (subject != null && !t.getSubject().equals(newSubject)) {
                return false;
            }
            if (predicate != null && !t.getPredicate().equals(newPredicate)) {
                return false;
            }
            if (object != null && !t.getObject().equals(newObject)) {
                return false;
            }
            return true;
        });
    }

    private Stream<Triple> getTriples(final Predicate<Triple> filter) {
        return stream().filter(filter);
    }

    @Override
    public void remove(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
        final Stream<Triple> toRemove = stream(subject, predicate, object);
        for (final Triple t : toRemove.collect(Collectors.toList())) {
            // Avoid ConcurrentModificationException in ArrayList
            remove(t);
        }
    }

    @Override
    public void remove(final Triple triple) {
        triples.remove(internallyMap(triple));
    }

    @Override
    public long size() {
        return triples.size();
    }

    @Override
    public String toString() {
        final String s = stream().limit(TO_STRING_MAX).map(Object::toString).collect(Collectors.joining("\n"));
        if (size() > TO_STRING_MAX) {
            return s + "\n# ... +" + (size() - TO_STRING_MAX) + " more";
        }
        return s;
    }

}
