/*
 * 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.rya.indexing.entity.storage.mongo;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import org.apache.rya.api.domain.RyaType;
import org.apache.rya.api.domain.RyaURI;
import org.apache.rya.indexing.entity.model.Entity;
import org.apache.rya.indexing.entity.model.Property;
import org.apache.rya.indexing.entity.model.Type;
import org.apache.rya.indexing.entity.model.TypedEntity;
import org.apache.rya.indexing.entity.storage.EntityStorage;
import org.apache.rya.indexing.entity.storage.EntityStorage.EntityAlreadyExistsException;
import org.apache.rya.indexing.entity.storage.EntityStorage.EntityStorageException;
import org.apache.rya.indexing.entity.storage.EntityStorage.StaleUpdateException;
import org.apache.rya.mongodb.MongoITBase;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import org.junit.Test;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

/**
 * Integration tests the methods of {@link MongoEntityStorage}.
 */
public class MongoEntityStorageIT extends MongoITBase {

    private static final String RYA_INSTANCE_NAME = "testInstance";

    @Test
    public void create_and_get() throws Exception {
        // An Entity that will be stored.
        final Entity entity = Entity.builder()
                .setSubject(new RyaURI("urn:GTIN-14/00012345600012"))
                .setExplicitType(new RyaURI("urn:icecream"))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Chocolate")))
                .build();

        // Create it.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        storage.create(entity);

        // Get it.
        final Optional<Entity> storedEntity = storage.get(new RyaURI("urn:GTIN-14/00012345600012"));

        // Verify the correct value was returned.
        assertEquals(entity, storedEntity.get());
    }

    @Test
    public void can_not_create_with_same_subject() throws Exception {
        // A Type that will be stored.
        final Entity entity = Entity.builder()
                .setSubject(new RyaURI("urn:GTIN-14/00012345600012"))
                .setExplicitType(new RyaURI("urn:icecream"))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Chocolate")))
                .build();

        // Create it.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        storage.create(entity);

        // Try to create it again. This will fail.
        boolean failed = false;
        try {
            storage.create(entity);
        } catch(final EntityAlreadyExistsException e) {
            failed = true;
        }
        assertTrue(failed);
    }

    @Test
    public void get_noneExisting() throws Exception {
        // Get a Type that hasn't been created.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        final Optional<Entity> storedEntity = storage.get(new RyaURI("urn:GTIN-14/00012345600012"));

        // Verify nothing was returned.
        assertFalse(storedEntity.isPresent());
    }

    @Test
    public void delete() throws Exception {
        // An Entity that will be stored.
        final Entity entity = Entity.builder()
                .setSubject(new RyaURI("urn:GTIN-14/00012345600012"))
                .setExplicitType(new RyaURI("urn:icecream"))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Chocolate")))
                .build();

        // Create it.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        storage.create(entity);

        // Delete it.
        final boolean deleted = storage.delete( new RyaURI("urn:GTIN-14/00012345600012") );

        // Verify a document was deleted.
        assertTrue( deleted );
    }

    @Test
    public void delete_nonExisting() throws Exception {
        // Delete an Entity that has not been created.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        final boolean deleted = storage.delete( new RyaURI("urn:GTIN-14/00012345600012") );

        // Verify no document was deleted.
        assertFalse( deleted );
    }

    @Test
    public void search_byDataType() throws Exception {
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);

        // The Type we will search by.
        final Type icecreamType = new Type(new RyaURI("urn:icecream"),
                ImmutableSet.<RyaURI>builder()
                    .add(new RyaURI("urn:brand"))
                    .add(new RyaURI("urn:flavor"))
                    .add(new RyaURI("urn:cost"))
                    .build());

        // Some Person typed entities.
        final Entity alice = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/111-11-1111") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        final Entity bob = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/222-22-2222") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Bob")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "57")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        // Some Icecream typed objects.
        final Entity chocolateIcecream = Entity.builder()
                .setSubject(new RyaURI("urn:GTIN-14/00012345600012"))
                .setExplicitType(new RyaURI("urn:icecream"))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Chocolate")))
                .build();

        final Entity vanillaIcecream = Entity.builder()
                .setSubject( new RyaURI("urn:GTIN-14/22356325213432") )
                .setExplicitType(new RyaURI("urn:icecream"))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Vanilla")))
                .build();


        final Entity strawberryIcecream = Entity.builder()
                .setSubject( new RyaURI("urn:GTIN-14/77544325436721") )
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:brand"), new RyaType(XMLSchema.STRING, "Awesome Icecream")))
                .setProperty(new RyaURI("urn:icecream"), new Property(new RyaURI("urn:flavor"), new RyaType(XMLSchema.STRING, "Strawberry")))
                .build();

        // Create the objects in the storage.
        storage.create(alice);
        storage.create(bob);
        storage.create(chocolateIcecream);
        storage.create(vanillaIcecream);
        storage.create(strawberryIcecream);

        // Search for all icecreams.
        final Set<TypedEntity> objects = new HashSet<>();
        try(final ConvertingCursor<TypedEntity> it = storage.search(Optional.empty(), icecreamType, new HashSet<>())) {
            while(it.hasNext()) {
                objects.add(it.next());
            }
        }

        // Verify the expected results were returned.
        final Set<TypedEntity> expected = Sets.newHashSet(
                chocolateIcecream.makeTypedEntity(new RyaURI("urn:icecream")).get(),
                vanillaIcecream.makeTypedEntity(new RyaURI("urn:icecream")).get());
        assertEquals(expected, objects);
    }

    @Test
    public void search_byFields() throws Exception {
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);

        // A Type that defines a Person.
        final Type personType = new Type(new RyaURI("urn:person"),
                ImmutableSet.<RyaURI>builder()
                    .add(new RyaURI("urn:name"))
                    .add(new RyaURI("urn:age"))
                    .add(new RyaURI("urn:eye"))
                    .build());

        // Some Person typed objects.
        final Entity alice = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/111-11-1111") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        final Entity bob = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/222-22-2222") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Bob")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "57")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();


        final Entity charlie = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/333-33-3333") )
                .setExplicitType( new RyaURI("urn:person") )
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Charlie")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        final Entity david = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/444-44-4444") )
                .setExplicitType( new RyaURI("urn:person") )
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "David")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "brown")))
                .build();

        final Entity eve = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/555-55-5555") )
                .setExplicitType( new RyaURI("urn:person") )
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Eve")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .build();

        final Entity frank = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/666-66-6666") )
                .setExplicitType( new RyaURI("urn:person") )
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Frank")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .setProperty(new RyaURI("urn:someOtherType"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .build();

        final Entity george = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/777-77-7777") )
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "George")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        // Create the objects in the storage.
        storage.create(alice);
        storage.create(bob);
        storage.create(charlie);
        storage.create(david);
        storage.create(eve);
        storage.create(frank);
        storage.create(george);

        // Search for all people who are 30 and have blue eyes.
        final Set<TypedEntity> objects = new HashSet<>();

        final Set<Property> searchValues = Sets.newHashSet(
                new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")),
                new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")));

        try(final ConvertingCursor<TypedEntity> it = storage.search(Optional.empty(), personType, searchValues)) {
            while(it.hasNext()) {
                objects.add(it.next());
            }
        }

        // Verify the expected results were returned.
        assertEquals(2, objects.size());
        assertTrue(objects.contains(alice.makeTypedEntity(new RyaURI("urn:person")).get()));
        assertTrue(objects.contains(charlie.makeTypedEntity(new RyaURI("urn:person")).get()));
    }

    @Test
    public void update() throws Exception {
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);

        // Store Alice in the repository.
        final Entity alice = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/111-11-1111") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        storage.create(alice);

        // Show Alice was stored.
        Optional<Entity> latest = storage.get(new RyaURI("urn:SSN/111-11-1111"));
        assertEquals(alice, latest.get());

        // Change Alice's eye color to brown.
        final Entity updated = Entity.builder(alice)
                .setVersion(latest.get().getVersion() + 1)
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "brown")))
                .build();

        storage.update(alice, updated);

        // Fetch the Alice object and ensure it has the new value.
        latest = storage.get(new RyaURI("urn:SSN/111-11-1111"));

        assertEquals(updated, latest.get());
    }

    @Test(expected = StaleUpdateException.class)
    public void update_stale() throws Exception {
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);

        // Store Alice in the repository.
        final Entity alice = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/111-11-1111") )
                .setExplicitType(new RyaURI("urn:person"))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")))
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")))
                .build();

        storage.create(alice);

        // Show Alice was stored.
        final Optional<Entity> latest = storage.get(new RyaURI("urn:SSN/111-11-1111"));
        assertEquals(alice, latest.get());

        // Create the wrong old state and try to change Alice's eye color to brown.
        final Entity wrongOld = Entity.builder(alice)
                .setVersion(500)
                .build();

        final Entity updated = Entity.builder(alice)
                .setVersion(501)
                .setProperty(new RyaURI("urn:person"), new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "brown")))
                .build();

        storage.update(wrongOld, updated);
    }

    @Test(expected = EntityStorageException.class)
    public void update_differentSubjects() throws Exception {
        // Two objects that do not have the same Subjects.
        final Entity old = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/111-11-1111") )
                .setExplicitType( new RyaURI("urn:person") )
                .build();

        final Entity updated = Entity.builder()
                .setSubject( new RyaURI("urn:SSN/222-22-2222") )
                .setExplicitType( new RyaURI("urn:person") )
                .build();

        // The update will fail.
        final EntityStorage storage = new MongoEntityStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
        storage.update(old, updated);
    }
}