/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ 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.sling.graphql.core.engine;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.sling.graphql.api.SchemaProvider;
import org.apache.sling.graphql.api.SelectedField;
import org.apache.sling.graphql.api.SelectionSet;
import org.apache.sling.graphql.api.SlingDataFetcher;
import org.apache.sling.graphql.api.SlingGraphQLException;
import org.apache.sling.graphql.api.engine.QueryExecutor;
import org.apache.sling.graphql.api.engine.ValidationResult;
import org.apache.sling.graphql.core.mocks.CharacterTypeResolver;
import org.apache.sling.graphql.core.mocks.DigestDataFetcher;
import org.apache.sling.graphql.core.mocks.DroidDTO;
import org.apache.sling.graphql.core.mocks.DummyTypeResolver;
import org.apache.sling.graphql.core.mocks.EchoDataFetcher;
import org.apache.sling.graphql.core.mocks.FailingDataFetcher;
import org.apache.sling.graphql.core.mocks.HumanDTO;
import org.apache.sling.graphql.core.mocks.MockSchemaProvider;
import org.apache.sling.graphql.core.mocks.TestUtil;
import org.apache.sling.graphql.core.schema.RankedSchemaProviders;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.junit.Test;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

import graphql.schema.idl.TypeDefinitionRegistry;

import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

public class DefaultQueryExecutorTest extends ResourceQueryTestBase {

    protected void setupAdditionalServices() {
        final Dictionary<String, Object> staticData = new Hashtable<>();
        staticData.put("test", true);

        HumanDTO human = new HumanDTO("human-1", "Luke", "Tatooine");
        DroidDTO droid = new DroidDTO("droid-1", "R2-D2", "whistle");

        final List<Object> characters = new ArrayList<>();
        characters.add(human);
        characters.add(droid);

        final Dictionary<String, Object> data = new Hashtable<>();
        data.put("characters", characters);

        TestUtil.registerSlingTypeResolver(context.bundleContext(), "character/resolver", new CharacterTypeResolver());
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "character/fetcher", new EchoDataFetcher(data));
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "echoNS/echo", new EchoDataFetcher(null));
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "failure/fail", new FailingDataFetcher());
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "test/static", new EchoDataFetcher(staticData));
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "test/fortyTwo", new EchoDataFetcher(42));
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "sling/digest", new DigestDataFetcher());

        final Dictionary<String, Object> dataCombined = new Hashtable<>();
        dataCombined.put("unionTest", characters);
        dataCombined.put("interfaceTest", characters);
        TestUtil.registerSlingDataFetcher(context.bundleContext(), "combined/fetcher", new EchoDataFetcher(dataCombined));
    }

    @Test
    public void basicTest() throws Exception {
        final String json = queryJSON("{ currentResource { path resourceType } }");
        assertThat(json, hasJsonPath("$.data.currentResource"));
        assertThat(json, hasJsonPath("$.data.currentResource.path", equalTo(resource.getPath())));
        assertThat(json, hasJsonPath("$.data.currentResource.resourceType", equalTo(resource.getResourceType())));
    }

    @Test
    public void staticContentTest() throws Exception {
        final String json = queryJSON("{ staticContent { test } }");
        assertThat(json, hasJsonPath("$.data.staticContent"));
        assertThat(json, hasJsonPath("$.data.staticContent.test", equalTo(true)));
    }

    @Test
    public void digestFieldsTest() throws Exception {
        final String json = queryJSON("{ currentResource { path pathMD5 pathSHA256 resourceTypeMD5 } }");

        final String pathMD5 = DigestDataFetcher.computeDigest("md5", resource.getPath());
        final String pathSHA256 = DigestDataFetcher.computeDigest("sha-256", resource.getPath());
        final String resourceTypeMD5 = DigestDataFetcher.computeDigest("md5", resource.getResourceType());

        assertThat(json, hasJsonPath("$.data.currentResource"));
        assertThat(json, hasJsonPath("$.data.currentResource.path", equalTo(resource.getPath())));
        assertThat(json, hasJsonPath("$.data.currentResource.pathMD5", equalTo("md5#path#" + pathMD5)));
        assertThat(json, hasJsonPath("$.data.currentResource.pathSHA256", equalTo("sha-256#path#" + pathSHA256)));
        assertThat(json, hasJsonPath("$.data.currentResource.resourceTypeMD5", equalTo("md5#resourceType#" + resourceTypeMD5)));
    }

    @Test
    public void nullValueTest() throws Exception {
        final String json = queryJSON("{ currentResource { nullValue } }");
        assertThat(json, hasJsonPath("$.data.currentResource"));
        assertThat(json, hasJsonPath("$.data.currentResource.nullValue", is(nullValue())));
    }

    @Test
    public void queryValidationErrorResponseTest() throws Exception {
        final String json = queryJSON("{ currentResource_NON_EXISTENT { nullValue } }");
        assertThat(json, hasJsonPath("$.errors[0].message"));
        assertThat(json, hasJsonPath("$.errors[0].locations"));
        assertThat(json, hasJsonPath("$.errors[0].extensions"));
        assertThat(json, hasJsonPath("$.errors[0].extensions.classification", is("ValidationError")));
    }

    @Test
    public void dataFetcherFailureTest() {
        try {
            final String stmt = "{ currentResource { failure } }";
            QueryExecutor queryExecutor = context.getService(QueryExecutor.class);
            assertNotNull(queryExecutor);
            queryExecutor.execute(stmt, Collections.emptyMap(), resource, new String[] {});
        } catch(RuntimeException rex) {
            assertThat(rex.getMessage(), containsString("Error: type=DataFetchingException; message=Exception while fetching data (/currentResource/failure) : FailingDataFetcher"));
        }
    }

    @Test
    public void invalidQueryTest() {
        final String stmt = "{ currentRsrc { failure } }";
        QueryExecutor queryExecutor = context.getService(QueryExecutor.class);
        assertNotNull(queryExecutor);
        ValidationResult result = queryExecutor.validate(stmt, Collections.emptyMap(), resource, new String[] {});
        assertFalse(result.isValid());
        String errors = String.join("\n", result.getErrors());
        assertTrue(errors.contains("Error: type=ValidationError; message=Validation error of type FieldUndefined: Field 'currentRsrc' in type 'Query' is undefined @ 'currentRsrc'; location=1,3;"));
    }

    @Test
    public void schemaSelectorsTest(){
        final String [] selectors = { "selected", "foryou" };
        final String json = queryJSON("{ currentResource { path fortyTwo } }", selectors);

        assertThat(json, hasJsonPath("$.data.currentResource"));
        assertThat(json, hasJsonPath("$.data.currentResource.path", equalTo(42)));
        assertThat(json, hasJsonPath("$.data.currentResource.fortyTwo", equalTo(42)));
    }

    @Test
    public void invalidFetcherNamesTest() {
        context.registerService(SchemaProvider.class, new MockSchemaProvider("failing-fetcher-schema"), Constants.SERVICE_RANKING,
                Integer.MAX_VALUE);
        final ServiceRegistration<?> reg = TestUtil.registerSlingDataFetcher(context.bundleContext(), "missingSlash", new EchoDataFetcher(42));
        try {
            final String json = queryJSON("{ currentResource { missingSlash } }", new String[] {});
            assertThat(json, hasJsonPath("$.errors[0].message", containsString("Invalid fetcher name missingSlash")));
            assertThat(json, hasJsonPath("$.errors[0].extensions.exception", is(SlingGraphQLException.class.getName())));
        } finally {
            reg.unregister();
        }
    }
    
    @Test
    public void invalidTypeResolverNamesTest() {
        context.registerService(SchemaProvider.class, new MockSchemaProvider("failing-type-resolver-schema"), Constants.SERVICE_RANKING,
                Integer.MAX_VALUE);
        final ServiceRegistration<?> reg = TestUtil.registerSlingTypeResolver(context.bundleContext(), "missingSlash",
                new DummyTypeResolver());
        try {
            final String json = queryJSON("{ currentResource { missingSlash } }", new String[] {});
            assertThat(json, hasJsonPath("$.errors[0].message", containsString("Invalid type resolver name missingSlash")));
            assertThat(json, hasJsonPath("$.errors[0].extensions.exception", is(SlingGraphQLException.class.getName())));
        } finally {
            reg.unregister();
        }
    }

    @Test
    public void unionQueryTest() throws Exception {
        final String json = queryJSON("{ unionQuery { characters { ... on Human { name address }  ... on Droid { name primaryFunction } } } }");
        assertThat(json, hasJsonPath("$.data.unionQuery"));
        assertThat(json, hasJsonPath("$.data.unionQuery.characters[0].name", equalTo("Luke")));
        assertThat(json, hasJsonPath("$.data.unionQuery.characters[0].address", equalTo("Tatooine")));
        assertThat(json, hasJsonPath("$.data.unionQuery.characters[1].name", equalTo("R2-D2")));
        assertThat(json, hasJsonPath("$.data.unionQuery.characters[1].primaryFunction", equalTo("whistle")));
    }

    @Test
    public void interfaceQueryTest() throws Exception {
        final String json = queryJSON("{ interfaceQuery { characters { id ... on Human { name address }  ... on Droid { name primaryFunction } } } }");
        assertThat(json, hasJsonPath("$.data.interfaceQuery"));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[0].id", equalTo("human-1")));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[0].name", equalTo("Luke")));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[0].address", equalTo("Tatooine")));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[1].id", equalTo("droid-1")));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[1].name", equalTo("R2-D2")));
        assertThat(json, hasJsonPath("$.data.interfaceQuery.characters[1].primaryFunction", equalTo("whistle")));
    }

    @Test
    public void selectionSetTest() throws Exception {
        queryJSON("{ combinedFetcher { boolValue resourcePath aTest { boolValue test resourcePath } allTests { boolValue test resourcePath } unionTest { ... on Human { id address } ... on Droid { id primaryFunction } } interfaceTest { id ... on Human { address } ... on Droid { primaryFunction } } } }");

        // retrieve the service used
        ServiceReference<?>[] serviceReferences = context.bundleContext().getServiceReferences(SlingDataFetcher.class.getName(), "(name=combined/fetcher)");
        EchoDataFetcher echoDataFetcher = (EchoDataFetcher) context.bundleContext().getService(serviceReferences[0]);

        // Access the computed SelectionSet
        SelectionSet selectionSet = echoDataFetcher.getSelectionSet();

        assertEquals(6, selectionSet.getFields().size());

        String[] expectedFieldNames = new String[] {
                "boolValue",
                "resourcePath",
                "aTest",
                "unionTest",
                "interfaceTest"
        };
        final List<SelectedField> selectionSetFields = selectionSet.getFields();
        for (String expectedFieldname : expectedFieldNames) {
            assertTrue(selectionSetFields.stream().anyMatch(f -> expectedFieldname.equals(f.getName())));
        }

        // Assert it contains the expected results
        String[] expectedQualifiedName = new String[] {
                "boolValue",
                "resourcePath",
                "aTest",
                "aTest/test",
                "aTest/boolValue",
                "aTest/resourcePath",
                "allTests",
                "allTests/test",
                "allTests/boolValue",
                "allTests/resourcePath",
                "unionTest",
                "unionTest/Human",
                "unionTest/Human/id",
                "unionTest/Human/address",
                "unionTest/Droid",
                "unionTest/Droid/id",
                "unionTest/Droid/primaryFunction",
                "interfaceTest",
                "interfaceTest/id",
                "interfaceTest/Human",
                "interfaceTest/Human/address",
                "interfaceTest/Droid",
                "interfaceTest/Droid/primaryFunction"
        };
        for (String expectedQN : expectedQualifiedName) {
            assertTrue(selectionSet.contains(expectedQN));
        }

        String[] expectedNonInlineQNs = new String[] {
                "boolValue",
                "resourcePath",
                "aTest",
                "aTest/test",
                "aTest/boolValue",
                "aTest/resourcePath",
                "allTests",
                "allTests/test",
                "allTests/boolValue",
                "allTests/resourcePath",
                "unionTest",
                "unionTest/Human/id",
                "unionTest/Human/address",
                "unionTest/Droid/id",
                "unionTest/Droid/primaryFunction",
                "interfaceTest",
                "interfaceTest/id",
                "interfaceTest/Human/address",
                "interfaceTest/Droid/primaryFunction"
        };
        for (String expectedNonInlineQN : expectedNonInlineQNs) {
            assertFalse(Objects.requireNonNull(selectionSet.get(expectedNonInlineQN)).isInline());
        }

        String[] expectedInlineQNs = new String[] {
                "unionTest/Human",
                "unionTest/Droid",
                "interfaceTest/Human",
                "interfaceTest/Droid"
        };
        for (String expectedInlineQN : expectedInlineQNs) {
            assertTrue(Objects.requireNonNull(selectionSet.get(expectedInlineQN)).isInline());
        }

        String[] expectedSubFieldNames = new String[] {
                "test",
                "boolValue",
                "resourcePath"
        };

        SelectedField allTests = selectionSet.get("allTests");
        assert allTests != null;
        List<SelectedField> subSelectedFields = allTests.getSubSelectedFields();
        for (String expectedSubFieldname : expectedSubFieldNames) {
            assertTrue(subSelectedFields.stream().anyMatch(f -> expectedSubFieldname.equals(f.getName())));
        }
    }

    @Test
    public void testCachedTypeRegistry() throws IOException {
        // by default we'll get the test-schema
        final DefaultQueryExecutor queryExecutor = (DefaultQueryExecutor) context.getService(QueryExecutor.class);
        final RankedSchemaProviders schemaProvider = context.getService(RankedSchemaProviders.class);
        assertNotNull(queryExecutor);
        assertNotNull(schemaProvider);
        String[] selectors = new String[]{};
        TypeDefinitionRegistry
                registry1 = queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        TypeDefinitionRegistry registry2 =
                queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        assertEquals(registry1, registry2);

        // change the schema provider
        context.registerService(SchemaProvider.class, new MockSchemaProvider("test-schema-selected-foryou"), Constants.SERVICE_RANKING,
                Integer.MAX_VALUE);
        TypeDefinitionRegistry
                registry3 = queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        TypeDefinitionRegistry registry4 =
                queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        assertEquals(registry1, registry2);
        assertEquals(registry3, registry4);
        assertNotEquals(registry1, registry3);
    }

    @Test
    public void testTypeRegistryWithTheCacheDisabled() throws IOException {
        Map<String, Object> properties = new HashMap<>();
        properties.put("schemaCacheSize", 0);

        DefaultQueryExecutor queryExecutor = (DefaultQueryExecutor) context.registerService(QueryExecutor.class, new DefaultQueryExecutor(),
                properties);
        MockOsgi.injectServices(queryExecutor, context.bundleContext(), properties);
        MockOsgi.activate(queryExecutor, context.bundleContext(), properties);

        final RankedSchemaProviders schemaProvider = context.getService(RankedSchemaProviders.class);
        assertNotNull(queryExecutor);
        assertNotNull(schemaProvider);
        String[] selectors = new String[]{};
        TypeDefinitionRegistry
                registry1 = queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        TypeDefinitionRegistry registry2 =
                queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        assertNotEquals(registry1, registry2);

        // change the schema provider
        context.registerService(SchemaProvider.class, new MockSchemaProvider("test-schema-selected-foryou"), Constants.SERVICE_RANKING,
                Integer.MAX_VALUE);
        TypeDefinitionRegistry
                registry3 = queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        TypeDefinitionRegistry registry4 =
                queryExecutor.getTypeDefinitionRegistry(schemaProvider.getSchema(resource, selectors), resource, selectors);
        assertNotEquals(registry3, registry4);
    }

}
