/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.atlas.web.resources;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.apache.atlas.AtlasServiceException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasQueryType;
import org.apache.atlas.model.instance.AtlasEntity.Status;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.typesystem.TypesDef;
import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.EnumTypeDefinition;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.StructTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import javax.ws.rs.core.MultivaluedMap;
import java.util.List;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;

/**
 * Search V2 Integration Tests.
 */
public class EntityDiscoveryJerseyResourceIT extends BaseResourceIT {
    private String dbName;

    @BeforeClass
    public void setUp() throws Exception {
        super.setUp();
        dbName = "database" + randomString();
        createTypes();
        createInstance(createHiveDBInstanceBuiltIn(dbName));
    }

    @Test
    public void testSearchByDSL() throws Exception {
        String dslQuery = "from "+ DATABASE_TYPE_BUILTIN + " " + QUALIFIED_NAME + "=\"" + dbName + "\"";

        AtlasSearchResult searchResult = atlasClientV2.dslSearch(dslQuery);
        assertNotNull(searchResult);
        assertEquals(searchResult.getQueryText(), dslQuery);
        assertEquals(searchResult.getQueryType(), AtlasQueryType.DSL);

        List<AtlasEntityHeader> entities = searchResult.getEntities();
        assertNotNull(entities);
        assertEquals(entities.size(), 1);

        AtlasEntityHeader dbEntity = entities.get(0);
        assertEquals(dbEntity.getTypeName(), DATABASE_TYPE_BUILTIN);
        assertEquals(dbEntity.getDisplayText(), dbName);
        assertEquals(dbEntity.getStatus(), Status.ACTIVE);
        assertNotNull(dbEntity.getGuid());
        assertNull(searchResult.getAttributes());
        assertNull(searchResult.getFullTextResult());
    }

    @Test
    public void testSearchDSLLimits() throws Exception {
        String dslQuery = "from "+ DATABASE_TYPE_BUILTIN + " " + QUALIFIED_NAME + "=\"" + dbName + "\"";
        AtlasSearchResult searchResult = atlasClientV2.dslSearch(dslQuery);
        assertNotNull(searchResult);

        //higher limit, all results returned
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, 10, 0);
        assertEquals(searchResult.getEntities().size(), 1);

        //default limit and offset -1, all results returned
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, -1, -1);
        assertEquals(searchResult.getEntities().size(), 1);

        //uses the limit parameter passed
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, 1, 0);
        assertEquals(searchResult.getEntities().size(), 1);

        //uses the offset parameter passed
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, 10, 1);
        assertNull(searchResult.getEntities());

        //limit > 0
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, 0, 10);
        assertNull(searchResult.getEntities());

        //limit > maxlimit
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, Integer.MAX_VALUE, 10);
        assertNull(searchResult.getEntities());

        //offset >= 0
        searchResult = atlasClientV2.dslSearchWithParams(dslQuery, 10, -2);
        assertEquals(searchResult.getEntities().size(), 1);
    }

    @Test(expectedExceptions = AtlasServiceException.class)
    public void testSearchByDSLForUnknownType() throws Exception {
        String dslQuery = "from blah";
        atlasClientV2.dslSearch(dslQuery);
    }

    @Test
    public void testSearchUsingDSL() throws Exception {
        String query = "from "+ DATABASE_TYPE_BUILTIN + " " + QUALIFIED_NAME + "=\"" + dbName + "\"";
        AtlasSearchResult searchResult = atlasClientV2.dslSearch(query);
        assertNotNull(searchResult);

        assertEquals(searchResult.getQueryText(), query);
        assertEquals(searchResult.getQueryType(), AtlasQueryType.DSL);
        List<AtlasEntityHeader> entities = searchResult.getEntities();
        assertNotNull(entities);
        assertEquals(entities.size(), 1);

        AtlasEntityHeader dbEntity = entities.get(0);
        assertEquals(dbEntity.getTypeName(), DATABASE_TYPE_BUILTIN);
        assertEquals(dbEntity.getDisplayText(), dbName);
        assertEquals(dbEntity.getStatus(), Status.ACTIVE);

        assertNotNull(dbEntity.getGuid());
        assertNull(searchResult.getAttributes());
        assertNull(searchResult.getFullTextResult());
    }

    @Test
    public void testLikeSearchUsingDSL() throws Exception {
        String dslQuery = DATABASE_TYPE_BUILTIN + " where " + QUALIFIED_NAME + " like \"da?a*\"";

        AtlasSearchResult searchResult = atlasClientV2.dslSearch(dslQuery);
        assertNotNull(searchResult);

        List<AtlasEntityHeader> entities = searchResult.getEntities();
        assertNotNull(entities);
        assertEquals(entities.size(), 1);

        AtlasEntityHeader dbEntity = entities.get(0);
        assertEquals(dbEntity.getTypeName(), DATABASE_TYPE_BUILTIN);
        assertEquals(dbEntity.getDisplayText(), dbName);
    }

    @Test
    public void testSearchFullTextOnDSLFailure() throws Exception {
        String query = "*";
        AtlasSearchResult searchResult = atlasClientV2.fullTextSearch(query);
        assertNotNull(searchResult);
        assertEquals(searchResult.getQueryText(), query);
        assertEquals(searchResult.getQueryType(), AtlasQueryType.FULL_TEXT);
    }

    @Test(dependsOnMethods = "testSearchDSLLimits")
    public void testSearchUsingFullText() throws Exception {
        AtlasSearchResult searchResult = atlasClientV2.fullTextSearchWithParams(dbName, 10, 0);
        assertNotNull(searchResult);

        assertEquals(searchResult.getQueryText(), dbName);
        assertEquals(searchResult.getQueryType(), AtlasQueryType.FULL_TEXT);

        List<AtlasFullTextResult> fullTextResults = searchResult.getFullTextResult();
        assertEquals(fullTextResults.size(), 1);

        AtlasFullTextResult result = fullTextResults.get(0);
        assertNotNull(result.getEntity());
        assertEquals(result.getEntity().getTypeName(), DATABASE_TYPE_BUILTIN);
        assertNotNull(result.getScore());

        //API works without limit and offset
        String query = dbName;
        MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
        queryParams.add("query", query);
        searchResult = atlasClientV2.fullTextSearch(query);
        assertNotNull(searchResult);
        assertEquals(searchResult.getFullTextResult().size(), 1);

        //verify passed in limits and offsets are used
        //higher limit and 0 offset returns all results
        searchResult = atlasClientV2.fullTextSearchWithParams(query, 10, 0);
        assertEquals(searchResult.getFullTextResult().size(), 1);

        //offset is used
        searchResult = atlasClientV2.fullTextSearchWithParams(query, 10, 1);
        assertEquals(searchResult.getFullTextResult().size(), 1);

        //limit is used
        searchResult = atlasClientV2.fullTextSearchWithParams(query, 1, 0);
        assertEquals(searchResult.getFullTextResult().size(), 1);

        //higher offset returns 0 results
        searchResult = atlasClientV2.fullTextSearchWithParams(query, 1, 2);
        assertEquals(searchResult.getFullTextResult().size(), 1);
    }

    private void createTypes() throws Exception {
        HierarchicalTypeDefinition<ClassType> dslTestTypeDefinition = TypesUtil
                .createClassTypeDef("dsl_test_type", ImmutableSet.<String>of(),
                        TypesUtil.createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE),
                        TypesUtil.createRequiredAttrDef("description", DataTypes.STRING_TYPE));

        HierarchicalTypeDefinition<TraitType> classificationTraitDefinition = TypesUtil
                .createTraitTypeDef("Classification", ImmutableSet.<String>of(),
                        TypesUtil.createRequiredAttrDef("tag", DataTypes.STRING_TYPE));
        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(),
                ImmutableList.of(classificationTraitDefinition), ImmutableList.of(dslTestTypeDefinition));
        createType(typesDef);
    }
}
