/*
 * 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.tinkerpop.gremlin.structure.util;

import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.AssertHelper;
import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Transaction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.io.Storage;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.apache.tinkerpop.gremlin.util.TestSupport;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class GraphFactoryTest {
    @Test
    public void shouldBeUtilityClass() throws Exception {
        AssertHelper.assertIsUtilityClass(GraphFactory.class);
    }

    @Test
    public void shouldThrowExceptionOnNullConfiguration() {
        try {
            GraphFactory.open((Configuration) null);
            fail("Should have thrown an exception since configuration is null");
        } catch (Exception ex) {
            final Exception expected = Graph.Exceptions.argumentCanNotBeNull("configuration");
            assertEquals(expected.getClass(), ex.getClass());
            assertEquals(expected.getMessage(), ex.getMessage());
        }
    }

    @Test
    public void shouldThrowExceptionOnNullMapConfiguration() {
        try {
            GraphFactory.open((Map) null);
            fail("Should have thrown an exception since configuration is null");
        } catch (Exception ex) {
            final Exception expected = Graph.Exceptions.argumentCanNotBeNull("configuration");
            assertEquals(expected.getClass(), ex.getClass());
            assertEquals(expected.getMessage(), ex.getMessage());
        }
    }

    @Test
    public void shouldThrowExceptionOnNullFileConfiguration() {
        try {
            GraphFactory.open((String) null);
            fail("Should have thrown an exception since configuration is null");
        } catch (Exception ex) {
            final Exception expected = Graph.Exceptions.argumentCanNotBeNull("configurationFile");
            assertEquals(expected.getClass(), ex.getClass());
            assertEquals(expected.getMessage(), ex.getMessage());
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void shouldThrowExceptionOnIfConfigurationFileIsNotAnActualFile() {
        GraphFactory.open(TestSupport.makeTestDataDirectory(GraphFactoryTest.class, "path"));
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphKeyIsNotPresentInConfiguration() {
        final Configuration conf = new BaseConfiguration();
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphKeyIsNotPresentInMapConfig() {
        final Map<String,Object> conf = new HashMap<>();
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphKeyIsNotValidClassInConfiguration() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, "not.a.real.class.that.is.a.SomeGraph");
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphKeyIsNotValidClassInMapConfig() {
        final Map<String,Object> conf = new HashMap<>();
        conf.put(Graph.GRAPH, "not.a.real.class.that.is.a.SomeGraph");
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphDoesNotHaveOpenMethodViaConfiguration() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraphWithoutOpen.class.getName());
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphDoesNotHaveOpenMethodViaMapConfig() {
        final Map<String,Object> conf = new HashMap<>();
        conf.put(Graph.GRAPH, MockGraphWithoutOpen.class.getName());
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphThrowsWhileConfiguringViaConfiguration() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraph.class.getName());
        conf.setProperty("throw", "it");
        GraphFactory.open(conf);
    }

    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfGraphThrowsWhileConfiguringViaMapConfig() {
        final Map<String,Object> conf = new HashMap<>();
        conf.put(Graph.GRAPH, MockGraph.class.getName());
        conf.put("throw", "it");
        GraphFactory.open(conf);
    }

    @Test
    public void shouldOpenViaConfiguration() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraph.class.getName());
        conf.setProperty("keep", "it");
        GraphFactory.open(conf);
        final MockGraph g = (MockGraph) GraphFactory.open(conf);
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaMapConfig() {
        final Map<String,Object> conf = new HashMap<>();
        conf.put(Graph.GRAPH, MockGraph.class.getName());
        conf.put("keep", "it");
        final MockGraph g = (MockGraph) GraphFactory.open(conf);
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaPropertiesFileConfig() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph.properties", ".properties");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaPropertiesFileConfigAsDefault() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph.properties", ".notrecognized");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaXmlFileConfig() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph.xml", ".xml");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaYamlFileConfig() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph.yaml", ".yaml");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenViaYmlFileConfig() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph.yaml", ".yml");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void shouldThrowOnInvalidConfigTypeViaFileConfig() throws IOException {
        final File confFile = TestSupport.generateTempFileFromResource(GraphFactoryTest.class, "mockgraph-busted.yaml", ".yaml");
        final MockGraph g = (MockGraph) GraphFactory.open(Storage.toPath(confFile));
        assertEquals(MockGraph.class.getName(), g.getConf().getString(Graph.GRAPH));
        assertEquals("it", g.getConf().getString("keep"));
    }

    @Test
    public void shouldOpenWithFactoryViaConcreteClass() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraphWithFactory.class.getName());
        GraphFactory.open(conf);
        final MockGraphWithFactory g = (MockGraphWithFactory) GraphFactory.open(conf);
        assertEquals(conf, g.getConf());
    }


    @Test
    public void shouldOpenWithFactoryViaConcreteInterface() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraphInterface.class.getName());
        GraphFactory.open(conf);
        final MockGraphInterface g = (MockGraphInterface) GraphFactory.open(conf);
        assertEquals(conf, g.getConf());
    }


    @Test(expected = RuntimeException.class)
    public void shouldThrowExceptionIfFactoryDoesNotHaveOpenMethodViaConfiguration() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, MockGraphWithFactoryWithoutOpen.class.getName());
        GraphFactory.open(conf);
    }

    @Test
    public void shouldCreateAnEmptyGraphInstance() {
        final Configuration conf = new BaseConfiguration();
        conf.setProperty(Graph.GRAPH, EmptyGraph.class.getName());
        final Graph graph = GraphFactory.open(conf);
        assertSame(EmptyGraph.instance(), graph);
    }

    public static class MockGraphWithoutOpen implements Graph {
        @Override
        public Vertex addVertex(final Object... keyValues) {
            return null;
        }

        @Override
        public <C extends GraphComputer> C compute(final Class<C> graphComputerClass) throws IllegalArgumentException {
            return null;
        }

        @Override
        public GraphComputer compute() throws IllegalArgumentException {
            return null;
        }

        @Override
        public Iterator<Vertex> vertices(final Object... vertexIds) {
            return null;
        }

        @Override
        public Iterator<Edge> edges(final Object... edgeIds) {
            return null;
        }

        @Override
        public Transaction tx() {
            return null;
        }

        @Override
        public Variables variables() {
            return null;
        }

        @Override
        public Configuration configuration() {
            return null;
        }

        @Override
        public void close() throws Exception {

        }
    }

    public static class MockGraph implements Graph {

        private final Configuration conf;
        MockGraph(final Configuration conf) {
            this.conf = conf;
        }

        public Configuration getConf() {
            return conf;
        }

        public static Graph open(final Configuration conf) {
            if (conf.containsKey("throw")) throw new RuntimeException("you said to throw me");
            return new MockGraph(conf);
        }

        @Override
        public Vertex addVertex(final Object... keyValues) {
            return null;
        }

        @Override
        public <C extends GraphComputer> C compute(final Class<C> graphComputerClass) throws IllegalArgumentException {
            return null;
        }

        @Override
        public GraphComputer compute() throws IllegalArgumentException {
            return null;
        }

        @Override
        public Iterator<Vertex> vertices(final Object... vertexIds) {
            return null;
        }

        @Override
        public Iterator<Edge> edges(final Object... edgeIds) {
            return null;
        }

        @Override
        public Transaction tx() {
            return null;
        }

        @Override
        public Variables variables() {
            return null;
        }

        @Override
        public Configuration configuration() {
            return null;
        }

        @Override
        public void close() throws Exception {

        }
    }

    public static class MockFactory {
        public static Graph open(final Configuration conf) {
            if (conf.containsKey("throw")) throw new RuntimeException("you said to throw me");
            return new MockGraphWithFactory(conf);
        }
    }

    @GraphFactoryClass(MockFactory.class)
    public static class MockGraphWithFactory implements MockGraphInterface {

        private final Configuration conf;

        MockGraphWithFactory(final Configuration conf) {
            this.conf = conf;
        }

        public Configuration getConf() {
            return conf;
        }

        @Override
        public Vertex addVertex(Object... keyValues) {
            return null;
        }

        @Override
        public <C extends GraphComputer> C compute(Class<C> graphComputerClass) throws IllegalArgumentException {
            return null;
        }

        @Override
        public GraphComputer compute() throws IllegalArgumentException {
            return null;
        }

        @Override
        public Iterator<Vertex> vertices(Object... vertexIds) {
            return null;
        }

        @Override
        public Iterator<Edge> edges(Object... edgeIds) {
            return null;
        }

        @Override
        public Transaction tx() {
            return null;
        }

        @Override
        public Variables variables() {
            return null;
        }

        @Override
        public Configuration configuration() {
            return null;
        }

        @Override
        public void close() throws Exception {

        }
    }


    public static class MockFactoryWithOutOpen {

    }

    @GraphFactoryClass(MockFactoryWithOutOpen.class)
    public static class MockGraphWithFactoryWithoutOpen implements Graph {

        private final Configuration conf;

        MockGraphWithFactoryWithoutOpen(final Configuration conf) {
            this.conf = conf;
        }

        public Configuration getConf() {
            return conf;
        }

        @Override
        public Vertex addVertex(Object... keyValues) {
            return null;
        }

        @Override
        public <C extends GraphComputer> C compute(Class<C> graphComputerClass) throws IllegalArgumentException {
            return null;
        }

        @Override
        public GraphComputer compute() throws IllegalArgumentException {
            return null;
        }

        @Override
        public Iterator<Vertex> vertices(Object... vertexIds) {
            return null;
        }

        @Override
        public Iterator<Edge> edges(Object... edgeIds) {
            return null;
        }

        @Override
        public Transaction tx() {
            return null;
        }

        @Override
        public Variables variables() {
            return null;
        }

        @Override
        public Configuration configuration() {
            return null;
        }

        @Override
        public void close() throws Exception {

        }
    }

    @GraphFactoryClass(MockFactory.class)
    public interface MockGraphInterface extends Graph {
        Configuration getConf();
    }
}
