package org.apache.rya.mongodb.instance;

/*
 * 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.
 */

import static org.junit.Assert.assertEquals;

import java.util.Date;

import org.apache.rya.api.instance.RyaDetails;
import org.apache.rya.api.instance.RyaDetails.EntityCentricIndexDetails;
import org.apache.rya.api.instance.RyaDetails.FreeTextIndexDetails;
import org.apache.rya.api.instance.RyaDetails.JoinSelectivityDetails;
import org.apache.rya.api.instance.RyaDetails.PCJIndexDetails;
import org.apache.rya.api.instance.RyaDetails.PCJIndexDetails.FluoDetails;
import org.apache.rya.api.instance.RyaDetails.PCJIndexDetails.PCJDetails;
import org.apache.rya.api.instance.RyaDetails.PCJIndexDetails.PCJDetails.PCJUpdateStrategy;
import org.apache.rya.api.instance.RyaDetails.ProspectorDetails;
import org.apache.rya.api.instance.RyaDetails.TemporalIndexDetails;
import org.apache.rya.mongodb.instance.MongoDetailsAdapter.MalformedRyaDetailsException;
import org.junit.Test;

import com.google.common.base.Optional;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

/**
 * Tests the methods of {@link MongoDetailsAdapter}.
 */
public class MongoDetailsAdapterTest {

    @Test
    public void ryaDetailsToMongoTest() {
        // Convert the Details into a Mongo DB OBject.
        final RyaDetails details = RyaDetails.builder()
                .setRyaInstanceName("test")
                .setRyaVersion("1")
                .setEntityCentricIndexDetails(new EntityCentricIndexDetails(true))
                //RYA-215            .setGeoIndexDetails(new GeoIndexDetails(true))
                .setPCJIndexDetails(
                        PCJIndexDetails.builder()
                        .setEnabled(true)
                        .setFluoDetails(new FluoDetails("fluo"))
                        .addPCJDetails(
                                PCJDetails.builder()
                                .setId("pcj_0")
                                .setUpdateStrategy(PCJUpdateStrategy.BATCH)
                                .setLastUpdateTime(new Date(0L)))
                        .addPCJDetails(
                                PCJDetails.builder()
                                .setId("pcj_1")
                                .setUpdateStrategy(PCJUpdateStrategy.BATCH)
                                .setLastUpdateTime(new Date(1L))))
                .setTemporalIndexDetails(new TemporalIndexDetails(true))
                .setFreeTextDetails(new FreeTextIndexDetails(true))
                .setProspectorDetails(new ProspectorDetails(Optional.fromNullable(new Date(0L))))
                .setJoinSelectivityDetails(new JoinSelectivityDetails(Optional.fromNullable(new Date(1L))))
                .build();

        final BasicDBObject actual = MongoDetailsAdapter.toDBObject(details);

        // Ensure it matches the expected object.
        final DBObject expected = (DBObject) JSON.parse(
                "{ "
                        + "instanceName : \"test\","
                        + "version : \"1\","
                        + "entityCentricDetails : true,"
                        //RYA-215            + "geoDetails : true,"
                        + "pcjDetails : {"
                        +    "enabled : true ,"
                        +    "pcjs : [ "
                        +       "{"
                        +          "id : \"pcj_0\","
                        +          "updateStrategy : \"BATCH\","
                        +          "lastUpdate : { $date : \"1970-01-01T00:00:00.000Z\"}"
                        +       "},"
                        +       "{"
                        +          "id : \"pcj_1\","
                        +          "updateStrategy : \"BATCH\","
                        +          "lastUpdate : { $date : \"1970-01-01T00:00:00.001Z\"}"
                        +       "}]"
                        + "},"
                        + "temporalDetails : true,"
                        + "freeTextDetails : true,"
                        + "prospectorDetails : { $date : \"1970-01-01T00:00:00.000Z\"},"
                        + "joinSelectivitiyDetails : { $date : \"1970-01-01T00:00:00.001Z\"}"
                        + "}"
                );

        assertEquals(expected.toString(), actual.toString());
    }

    @Test
    public void mongoToRyaDetailsTest() throws MalformedRyaDetailsException {
        // Convert the Mongo object into a RyaDetails.
        final BasicDBObject mongo = (BasicDBObject) JSON.parse(
                "{ "
                        + "instanceName : \"test\","
                        + "version : \"1\","
                        + "entityCentricDetails : true,"
                        //RYA-215            + "geoDetails : true,"
                        + "pcjDetails : {"
                        +    "enabled : true ,"
                        +    "fluoName : \"fluo\","
                        +    "pcjs : [ "
                        +       "{"
                        +          "id : \"pcj_0\","
                        +          "updateStrategy : \"BATCH\","
                        +          "lastUpdate : { $date : \"1970-01-01T00:00:00.000Z\"}"
                        +       "},"
                        +       "{"
                        +          "id : \"pcj_1\","
                        +          "updateStrategy : \"BATCH\","
                        +          "lastUpdate : { $date : \"1970-01-01T00:00:00.001Z\"}"
                        +       "}]"
                        + "},"
                        + "temporalDetails : true,"
                        + "freeTextDetails : true,"
                        + "prospectorDetails : { $date : \"1970-01-01T00:00:00.000Z\"},"
                        + "joinSelectivitiyDetails : { $date : \"1970-01-01T00:00:00.001Z\"}"
                        + "}"
                );

        final RyaDetails actual = MongoDetailsAdapter.toRyaDetails(mongo);

        // Ensure it matches the expected object.
        final RyaDetails expected = RyaDetails.builder()
                .setRyaInstanceName("test")
                .setRyaVersion("1")
                .setEntityCentricIndexDetails(new EntityCentricIndexDetails(true))
                //RYA-215            .setGeoIndexDetails(new GeoIndexDetails(true))
                .setPCJIndexDetails(
                        PCJIndexDetails.builder()
                        .setEnabled(true)
                        .addPCJDetails(
                                PCJDetails.builder()
                                .setId("pcj_0")
                                .setUpdateStrategy(PCJUpdateStrategy.BATCH)
                                .setLastUpdateTime(new Date(0L)))
                        .addPCJDetails(
                                PCJDetails.builder()
                                .setId("pcj_1")
                                .setUpdateStrategy(PCJUpdateStrategy.BATCH)
                                .setLastUpdateTime(new Date(1L))))
                .setTemporalIndexDetails(new TemporalIndexDetails(true))
                .setFreeTextDetails(new FreeTextIndexDetails(true))
                .setProspectorDetails(new ProspectorDetails(Optional.<Date>fromNullable(new Date(0L))))
                .setJoinSelectivityDetails(new JoinSelectivityDetails(Optional.<Date>fromNullable(new Date(1L))))
                .build();

        assertEquals(expected, actual);
    }

    @Test
    public void absentOptionalToRyaDetailsTest() throws MalformedRyaDetailsException {
        // Convert the Mongo object into a RyaDetails.
        final BasicDBObject mongo = (BasicDBObject) JSON.parse(
                "{ "
                        + "instanceName : \"test\","
                        + "version : \"1\","
                        + "entityCentricDetails : true,"
                        //RYA-215                + "geoDetails : false,"
                        + "pcjDetails : {"
                        +    "enabled : false,"
                        +    "pcjs : [ "
                        +       "{"
                        +          "id : \"pcj_1\","
                        +       "}"
                        +    "]"
                        + "},"
                        + "temporalDetails : false,"
                        + "freeTextDetails : true,"
                        + "prospectorDetails : null,"
                        + "joinSelectivitiyDetails : null"
                        + "}"
                );
        final RyaDetails actual = MongoDetailsAdapter.toRyaDetails(mongo);

        // Ensure it matches the expected object.
        final RyaDetails expected = RyaDetails.builder()
                .setRyaInstanceName("test")
                .setRyaVersion("1")
                .setEntityCentricIndexDetails(new EntityCentricIndexDetails(true))
                //RYA-215            .setGeoIndexDetails(new GeoIndexDetails(false))
                .setPCJIndexDetails(
                        PCJIndexDetails.builder()
                        .setEnabled(false))
                .setTemporalIndexDetails(new TemporalIndexDetails(false))
                .setFreeTextDetails(new FreeTextIndexDetails(true))
                .setProspectorDetails(new ProspectorDetails(Optional.<Date>absent()))
                .setJoinSelectivityDetails(new JoinSelectivityDetails(Optional.<Date>absent()))
                .build();

        assertEquals(expected, actual);
    }

    @Test
    public void absentOptionalToMongoTest() {
        // Convert the Details into a Mongo DB OBject.
        final RyaDetails details = RyaDetails.builder()
                .setRyaInstanceName("test")
                .setRyaVersion("1")
                .setEntityCentricIndexDetails(new EntityCentricIndexDetails(true))
                //RYA-215            .setGeoIndexDetails(new GeoIndexDetails(false))
                .setPCJIndexDetails(
                        PCJIndexDetails.builder()
                        .setEnabled(true)
                        .setFluoDetails(new FluoDetails("fluo")))
                .setTemporalIndexDetails(new TemporalIndexDetails(false))
                .setFreeTextDetails(new FreeTextIndexDetails(true))
                .setProspectorDetails(new ProspectorDetails(Optional.<Date>absent()))
                .setJoinSelectivityDetails(new JoinSelectivityDetails(Optional.<Date>absent()))
                .build();

        final DBObject actual = MongoDetailsAdapter.toDBObject(details);

        // Ensure it matches the expected object.
        final BasicDBObject expected = (BasicDBObject) JSON.parse(
                "{ "
                        + "instanceName : \"test\","
                        + "version : \"1\","
                        + "entityCentricDetails : true,"
                        //RYA-215                + "geoDetails : false,"
                        + "pcjDetails : {"
                        +    "enabled : true,"
                        +    "pcjs : [ ]"
                        + "},"
                        + "temporalDetails : false,"
                        + "freeTextDetails : true"
                        + "}"
                );
        assertEquals(expected, actual);
    }

    @Test
    public void toDBObject_pcjDetails() {
        final PCJDetails details = PCJDetails.builder()
                .setId("pcjId")
                .setLastUpdateTime( new Date() )
                .setUpdateStrategy( PCJUpdateStrategy.INCREMENTAL )
                .build();

        // Convert it into a Mongo DB Object.
        final BasicDBObject dbo = (BasicDBObject) MongoDetailsAdapter.toDBObject(details);

        // Convert the dbo back into the original object.
        final PCJDetails restored = MongoDetailsAdapter.toPCJDetails(dbo).build();

        // Ensure the restored value matches the original.
        assertEquals(details, restored);
    }

    @Test
    public void toDBObject_pcjDetails_missing_optionals() {
        final PCJDetails details = PCJDetails.builder()
                .setId("pcjId")
                .build();

        // Convert it into a Mongo DB Object.
        final BasicDBObject dbo = (BasicDBObject) MongoDetailsAdapter.toDBObject(details);

        // Convert the dbo back into the original object.
        final PCJDetails restored = MongoDetailsAdapter.toPCJDetails(dbo).build();

        // Ensure the restored value matches the original.
        assertEquals(details, restored);
    }
}