/**
 * 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.falcon.resource.proxy;

import org.apache.commons.lang.StringUtils;
import org.apache.falcon.FalconException;
import org.apache.falcon.FalconWebException;
import org.apache.falcon.entity.EntityUtil;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.extensions.jdbc.ExtensionMetaStore;
import org.apache.falcon.extensions.store.ExtensionStore;
import org.apache.falcon.monitors.Dimension;
import org.apache.falcon.monitors.Monitored;
import org.apache.falcon.resource.APIResult;
import org.apache.falcon.resource.AbstractExtensionManager;
import org.apache.falcon.resource.AbstractSchedulableEntityManager;
import org.apache.falcon.resource.EntityList;
import org.apache.falcon.resource.EntitySummaryResult;
import org.apache.falcon.resource.FeedLookupResult;
import org.apache.falcon.resource.SchedulableEntityInstanceResult;
import org.apache.falcon.util.DeploymentUtil;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * A proxy implementation of the schedulable entity operations.
 */
@Path("entities")
public class SchedulableEntityManagerProxy extends AbstractSchedulableEntityManager {
    static final String PRISM_TAG = "prism";
    static final String FALCON_TAG = "falcon";

    private EntityProxyUtil entityProxyUtil = new EntityProxyUtil();
    private boolean embeddedMode = DeploymentUtil.isEmbeddedMode();
    private String currentColo = DeploymentUtil.getCurrentColo();

    private BufferedRequest getBufferedRequest(HttpServletRequest request) {
        if (request instanceof BufferedRequest) {
            return (BufferedRequest) request;
        }
        return new BufferedRequest(request);
    }

    @GET
    @Path("sla-alert/{type}")
    @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
    @Monitored(event = "entity-sla-misses")
    public SchedulableEntityInstanceResult getEntitySLAMissPendingAlerts(
            @Dimension("entityType") @PathParam("type") final String entityType,
            @Dimension("entityName") @QueryParam("name") final String entityName,
            @Dimension("start") @QueryParam("start") final String start,
            @Dimension("end") @QueryParam("end") final String end,
            @Dimension("colo") @QueryParam("colo") final String colo) {
        try {
            validateSlaParams(entityType, entityName, start, end, colo);
        } catch (Exception e) {
            throw FalconWebException.newAPIException(e);
        }
        return new EntityProxy<SchedulableEntityInstanceResult>(entityType, entityName,
                SchedulableEntityInstanceResult.class) {
            @Override
            protected Set<String> getColosToApply() {
                return getApplicableColos(entityType, entityName);
            }

            @Override
            protected SchedulableEntityInstanceResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("getEntitySLAMissPendingAlerts", entityType,
                        entityName, start, end, colo);
            }
        }.execute();
    }

    /**
     * Submit the given entity.
     * @param request Servlet Request
     * @param type Valid options are cluster, feed or process.
     * @param ignore colo is ignored
     * @return Result of the submission.
     */
    @POST
    @Path("submit/{type}")
    @Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "submit")
    @Override
    public APIResult submit(
            @Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
            @Dimension("colo") @QueryParam("colo") final String ignore) {

        final HttpServletRequest bufferedRequest = getBufferedRequest(request);

        final Entity entity = getEntity(bufferedRequest, type);
        Map<String, APIResult> results = new HashMap<>();
        final Set<String> colos = getApplicableColos(type, entity);

        entityHasExtensionJobTag(entity);
        validateEntity(entity, colos);

        results.putAll(entityProxyUtil.proxySubmit(type, bufferedRequest, entity, colos));
        if (!embeddedMode) {
            results.put(PRISM_TAG, super.submit(bufferedRequest, type, currentColo));
        }
        return consolidateResult(results, APIResult.class);
    }

    private void validateEntity(Entity entity, Set<String> applicableColos) {
        if (entity.getEntityType() != EntityType.CLUSTER || embeddedMode) {
            return;
        }
        // If the submitted entity is a cluster, ensure its spec. has one of the valid colos
        String colo = ((Cluster) entity).getColo();
        if (!applicableColos.contains(colo)) {
            throw FalconWebException.newAPIException("The colo mentioned in the cluster specification, "
                    + colo + ", is not listed in Prism runtime.");
        }
    }

    private Entity getEntity(HttpServletRequest request, String type) {
        try {
            request.getInputStream().reset();
            Entity entity = deserializeEntity(request.getInputStream(), EntityType.getEnum(type));
            request.getInputStream().reset();
            return entity;
        } catch (Exception e) {
            throw FalconWebException.newAPIException(e);
        }
    }

    /**
     * Validates the submitted entity.
     * @param request Servlet Request
     * @param type Valid options are cluster, feed or process.
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the validation.
     */
    @POST
    @Path("validate/{type}")
    @Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Override
    public APIResult validate(@Context final HttpServletRequest request, @PathParam("type") final String type,
                              @QueryParam("skipDryRun") final Boolean skipDryRun) {
        final HttpServletRequest bufferedRequest = getBufferedRequest(request);
        EntityType entityType = EntityType.getEnum(type);
        final Entity entity;
        try {
            entity = deserializeEntity(bufferedRequest.getInputStream(), entityType);
            bufferedRequest.getInputStream().reset();
        } catch (Exception e) {
            throw FalconWebException.newAPIException("Unable to parse entity definition");
        }
        return new EntityProxy(type, entity.getName()) {
            @Override
            protected Set<String> getColosToApply() {
                return getApplicableColos(type, entity);
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("validate", bufferedRequest, type,
                        skipDryRun);
            }
        }.execute();
    }

    /**
     * Delete the specified entity.
     * @param request Servlet Request
     * @param type Valid options are cluster, feed or process.
     * @param entityName Name of the entity.
     * @param ignore colo is ignored
     * @return Results of the delete operation.
     */
    @DELETE
    @Path("delete/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "delete")
    @Override
    public APIResult delete(
            @Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
            @Dimension("entityName") @PathParam("entity") final String entityName,
            @Dimension("colo") @QueryParam("colo") String ignore) {

        try {
            isEntityPartOfAnExtension(EntityUtil.getEntity(type, entityName));
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e);
        }
        final HttpServletRequest bufferedRequest = new BufferedRequest(request);
        Map<String, APIResult> results = new HashMap<>();
        results.putAll(entityProxyUtil.proxyDelete(type, entityName, bufferedRequest));
        // delete only if deleted from everywhere
        if (!embeddedMode && results.get(FALCON_TAG).getStatus() == APIResult.Status.SUCCEEDED) {
            results.put(PRISM_TAG, super.delete(bufferedRequest, type, entityName, currentColo));
        }
        return consolidateResult(results, APIResult.class);
    }

    /**
     * Updates the submitted entity.
     * @param request Servlet Request
     * @param type Valid options are feed or process.
     * @param entityName Name of the entity.
     * @param ignore colo is ignored
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the validation.
     */
    @POST
    @Path("update/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "update")
    @Override
    public APIResult update(
            @Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
            @Dimension("entityName") @PathParam("entity") final String entityName,
            @Dimension("colo") @QueryParam("colo") String ignore,
            @QueryParam("skipDryRun") final Boolean skipDryRun) {

        try {
            isEntityPartOfAnExtension(EntityUtil.getEntity(type, entityName));
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e);
        }
        final HttpServletRequest bufferedRequest = new BufferedRequest(request);
        Entity newEntity = getEntity(bufferedRequest, type);
        entityHasExtensionJobTag(newEntity);

        Map<String, APIResult> results = new HashMap<>();
        boolean result = true;
        results.putAll(entityProxyUtil.proxyUpdate(type, entityName, skipDryRun, bufferedRequest, newEntity));

        for (APIResult apiResult : results.values()) {
            if (apiResult.getStatus() != APIResult.Status.SUCCEEDED) {
                result = false;
            }
        }

        // update only if all are updated
        if (!embeddedMode && result) {
            results.put(PRISM_TAG, super.update(bufferedRequest, type, entityName, currentColo, skipDryRun));
        }

        return consolidateResult(results, APIResult.class);
    }

    private void isEntityPartOfAnExtension(Entity entity) {
        String tags = entity.getTags();
        checkExtensionJobExist(tags);
    }


    private void entityHasExtensionJobTag(Entity entity) {
        String tags = entity.getTags();
        if (StringUtils.isNotBlank(tags)) {
            String jobName = AbstractExtensionManager.getJobNameFromTag(tags);
            if (StringUtils.isNotBlank(jobName)) {
                throw FalconWebException.newAPIException("Entity has extension job name in the tag. Such entities need "
                        + "to be submitted as extension jobs:" + jobName);
            }
        }
    }

    private void checkExtensionJobExist(String tags) {
        if (tags != null) {
            String jobName = AbstractExtensionManager.getJobNameFromTag(tags);
            ExtensionMetaStore extensionMetaStore = ExtensionStore.getMetaStore();
            if (jobName != null && extensionMetaStore.checkIfExtensionJobExists(jobName)) {
                throw FalconWebException.newAPIException("Entity operation is not allowed on this entity as it is"
                        + "part of an extension job:" + jobName);
            }
        }
    }

    /**
     * Updates the dependent entities of a cluster in workflow engine.
     * @param clusterName Name of cluster.
     * @param ignore colo.
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the validation.
     */
    @POST
    @Path("updateClusterDependents/{clusterName}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "updateClusterDependents")
    @Override
    public APIResult updateClusterDependents(
            @Dimension("entityName") @PathParam("clusterName") final String clusterName,
            @Dimension("colo") @QueryParam("colo") String ignore,
            @QueryParam("skipDryRun") final Boolean skipDryRun) {

        final Set<String> allColos = getApplicableColos("cluster", clusterName);
        Map<String, APIResult> results = new HashMap<String, APIResult>();
        boolean result = true;

        if (!allColos.isEmpty()) {
            results.put(FALCON_TAG + "/updateClusterDependents", new EntityProxy("cluster", clusterName) {
                @Override
                protected Set<String> getColosToApply() {
                    return allColos;
                }

                @Override
                protected APIResult doExecute(String colo) throws FalconException {
                    return entityProxyUtil.getConfigSyncChannel(colo).invoke("updateClusterDependents",
                            clusterName, colo, skipDryRun);
                }
            }.execute());
        }

        for (APIResult apiResult : results.values()) {
            if (apiResult.getStatus() != APIResult.Status.SUCCEEDED) {
                result = false;
            }
        }
        // update only if all are updated
        if (!embeddedMode && result) {
            results.put(PRISM_TAG, super.updateClusterDependents(clusterName, currentColo, skipDryRun));
        }

        return consolidateResult(results, APIResult.class);
    }

    /**
     * Force updates the entity.
     * @param type Valid options are feed or process.
     * @param entityName Name of the entity.
     * @param coloExpr Colo on which the query should be run.
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the validation.
     */
    @POST
    @Path("touch/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "touch")
    @Override
    public APIResult touch(
            @Dimension("entityType") @PathParam("type") final String type,
            @Dimension("entityName") @PathParam("entity") final String entityName,
            @Dimension("colo") @QueryParam("colo") final String coloExpr,
            @QueryParam("skipDryRun") final Boolean skipDryRun) {
        final Set<String> colosFromExp = getColosFromExpression(coloExpr, type, entityName);
        return new EntityProxy(type, entityName) {
            @Override
            protected Set<String> getColosToApply() {
                return colosFromExp;
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("touch", type, entityName, colo, skipDryRun);
            }
        }.execute();
    }

    /**
     * Get status of the entity.
     * @param type Valid options are cluster, feed or process.
     * @param entity Name of the entity.
     * @param coloExpr Colo on which the query should be run.
     * @param showScheduler whether the call should return the scheduler on which the entity is scheduled.
     * @return Status of the entity.
     */
    @GET
    @Path("status/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "status")
    @Override
    public APIResult getStatus(@Dimension("entityType") @PathParam("type") final String type,
                               @Dimension("entityName") @PathParam("entity") final String entity,
                               @Dimension("colo") @QueryParam("colo") final String coloExpr,
                               @Dimension("showScheduler") @QueryParam("showScheduler") final Boolean showScheduler) {
        return new EntityProxy(type, entity) {
            @Override
            protected Set<String> getColosToApply() {
                return getColosFromExpression(coloExpr, type, entity);
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("getStatus", type, entity, colo,
                        showScheduler);
            }
        }.execute();
    }

    /**
     * Get dependencies of the entity.
     * @param type Valid options are cluster, feed or process.
     * @param entity Name of the entity.
     * @return Dependencies of the entity.
     */
    @GET
    @Path("dependencies/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
    @Monitored(event = "dependencies")
    @Override
    public EntityList getDependencies(@Dimension("entityType") @PathParam("type") String type,
                                      @Dimension("entityName") @PathParam("entity") String entity) {
        return super.getDependencies(type, entity);
    }

    /**
     * Get definition of the entity.
     * @param type Valid options are cluster, feed or process.
     * @param entityName Name of the entity.
     * @return Definition of the entity.
     */
    @GET
    @Path("definition/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Override
    public String getEntityDefinition(@PathParam("type") String type, @PathParam("entity") String entityName) {
        return super.getEntityDefinition(type, entityName);
    }

    /**
     * Schedule an entity.
     * @param request Servlet Request
     * @param type Valid options are feed or process.
     * @param entity Name of the entity.
     * @param coloExpr Colo on which the query should be run.
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the schedule command.
     */
    @POST
    @Path("schedule/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "schedule")
    @Override
    public APIResult schedule(@Context final HttpServletRequest request,
                              @Dimension("entityType") @PathParam("type") final String type,
                              @Dimension("entityName") @PathParam("entity") final String entity,
                              @Dimension("colo") @QueryParam("colo") final String coloExpr,
                              @QueryParam("skipDryRun") final Boolean skipDryRun,
                              @QueryParam("properties") final String properties) {

        final HttpServletRequest bufferedRequest = getBufferedRequest(request);
        return new EntityProxy(type, entity) {
            @Override
            protected Set<String> getColosToApply() {
                return getColosFromExpression(coloExpr, type, entity);
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("schedule", bufferedRequest, type, entity,
                        colo, skipDryRun, properties);
            }
        }.execute();
    }

    /**
     * Submits and schedules an entity.
     * @param request Servlet Request
     * @param type Valid options are feed or process.
     * @param coloExpr Colo on which the query should be run.
     * @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
     * @return Result of the submit and schedule command.
     */
    @POST
    @Path("submitAndSchedule/{type}")
    @Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "submitAndSchedule")
    @Override
    public APIResult submitAndSchedule(
            @Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") String type,
            @Dimension("colo") @QueryParam("colo") String coloExpr,
            @QueryParam("skipDryRun") Boolean skipDryRun,
            @QueryParam("properties") String properties) {
        BufferedRequest bufferedRequest = new BufferedRequest(request);
        final Entity entity = getEntity(bufferedRequest, type);
        String entityName = entity.getName();
        entityHasExtensionJobTag(entity);
        Map<String, APIResult> results = new HashMap<String, APIResult>();
        results.put("submit", submit(bufferedRequest, type, coloExpr));
        results.put("schedule", schedule(bufferedRequest, type, entityName, coloExpr, skipDryRun, properties));
        return consolidateResult(results, APIResult.class);
    }

    /**
     * Suspend an entity.
     * @param request Servlet Requests
     * @param type Valid options are feed or process.
     * @param entity Name of the entity.
     * @param coloExpr Colo on which the query should be run.
     * @return Status of the entity.
     */
    @POST
    @Path("suspend/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "suspend")
    @Override
    public APIResult suspend(@Context final HttpServletRequest request,
                             @Dimension("entityType") @PathParam("type") final String type,
                             @Dimension("entityName") @PathParam("entity") final String entity,
                             @Dimension("colo") @QueryParam("colo") final String coloExpr) {

        final HttpServletRequest bufferedRequest = new BufferedRequest(request);
        return new EntityProxy(type, entity) {
            @Override
            protected Set<String> getColosToApply() {
                return getColosFromExpression(coloExpr, type, entity);
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("suspend", bufferedRequest, type, entity,
                        colo);
            }
        }.execute();
    }

    /**
     * Resume a supended entity.
     * @param request Servlet Request
     * @param type Valid options are feed or process.
     * @param entity Name of the entity.
     * @param coloExpr Colo on which the query should be run.
     * @return Result of the resume command.
     */
    @POST
    @Path("resume/{type}/{entity}")
    @Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    @Monitored(event = "resume")
    @Override
    public APIResult resume(
            @Context final HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
            @Dimension("entityName") @PathParam("entity") final String entity,
            @Dimension("colo") @QueryParam("colo") final String coloExpr) {

        final HttpServletRequest bufferedRequest = new BufferedRequest(request);
        return new EntityProxy(type, entity) {
            @Override
            protected Set<String> getColosToApply() {
                return getColosFromExpression(coloExpr, type, entity);
            }

            @Override
            protected APIResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("resume", bufferedRequest, type, entity,
                        colo);
            }
        }.execute();
    }

    //SUSPEND CHECKSTYLE CHECK ParameterNumberCheck

    /**
     *
     * Get list of the entities.
     * We have two filtering parameters for entity tags: "tags" and "tagkeys".
     * "tags" does the exact match in key=value fashion, while "tagkeys" finds all the entities with the given key as a
     * substring in the tags. This "tagkeys" filter is introduced for the user who doesn't remember the exact tag but
     * some keywords in the tag. It also helps users to save the time of typing long tags.
     * The returned entities will match all the filtering criteria.
     * @param type Comma-separated entity types. Can be empty. Valid entity types are cluster, feed or process.
     * @param fields <optional param> Fields of entity that the user wants to view, separated by commas.
     *               Valid options are STATUS, TAGS, PIPELINES, CLUSTERS.
     * @param nameSubsequence <optional param> Subsequence of entity name. Not case sensitive.
     *                        The entity name needs to contain all the characters in the subsequence in the same order.
     *                        Example 1: "sample1" will match the entity named "SampleFeed1-2".
     *                        Example 2: "mhs" will match the entity named "New-My-Hourly-Summary".
     * @param tagKeywords <optional param> Keywords in tags, separated by comma. Not case sensitive.
     *                    The returned entities will have tags that match all the tag keywords.
     * @param tags <optional param> Return list of entities that have specified tags, separated by a comma.
     *             Query will do AND on tag values.
     *             Example: tags=consumer=consumer@xyz.com,owner=producer@xyz.com
     * @param filterBy <optional param> Filter results by list of field:value pairs.
     *                 Example: filterBy=STATUS:RUNNING,PIPELINES:clickLogs
     *                 Supported filter fields are NAME, STATUS, PIPELINES, CLUSTER.
     *                 Query will do an AND among filterBy fields.
     * @param orderBy <optional param> Field by which results should be ordered.
     *                Supports ordering by "name".
     * @param sortOrder <optional param> Valid options are "asc" and "desc"
     * @param offset <optional param> Show results from the offset, used for pagination. Defaults to 0.
     * @param resultsPerPage <optional param> Number of results to show per request, used for pagination. Only
     *                       integers > 0 are valid, Default is 10.
     * @return Total number of results and a list of entities.
     */
    @GET
    @Path("list{type : (/[^/]+)?}")
    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
    @Monitored(event = "list")
    @Override
    public EntityList getEntityList(@PathParam("type") String type,
                                    @DefaultValue("") @QueryParam("fields") String fields,
                                    @DefaultValue("") @QueryParam("nameseq") String nameSubsequence,
                                    @DefaultValue("") @QueryParam("tagkeys") String tagKeywords,
                                    @DefaultValue("") @QueryParam("tags") String tags,
                                    @DefaultValue("") @QueryParam("filterBy") String filterBy,
                                    @DefaultValue("") @QueryParam("orderBy") String orderBy,
                                    @DefaultValue("asc") @QueryParam("sortOrder") String sortOrder,
                                    @DefaultValue("0") @QueryParam("offset") Integer offset,
                                    @QueryParam("numResults") Integer resultsPerPage,
                                    @QueryParam("doAs") String doAsUser) {
        if (StringUtils.isNotEmpty(type)) {
            type = type.substring(1);
        }
        resultsPerPage = resultsPerPage == null ? getDefaultResultsPerPage() : resultsPerPage;
        return super.getEntityList(fields, nameSubsequence, tagKeywords, type, tags, filterBy,
                orderBy, sortOrder, offset, resultsPerPage, doAsUser);
    }

    /**
     * Given an EntityType and cluster, get list of entities along with summary of N recent instances of each entity.
     * @param type Valid options are feed or process.
     * @param clusterName Show entities that belong to this cluster.
     * @param startStr <optional param> Show entity summaries from this date. Date format is yyyy-MM-dd'T'HH:mm'Z'.
     *                 By default, it is set to (end - 2 days).
     * @param endStr <optional param> Show entity summary up to this date. Date format is yyyy-MM-dd'T'HH:mm'Z'.
     *               Default is set to now.
     * @param entityFields <optional param> Fields of entity that the user wants to view, separated by commas.
     *                     Valid options are STATUS, TAGS, PIPELINES.
     * @param entityFilter <optional param> Filter results by list of field:value pairs.
     *                     Example: filterBy=STATUS:RUNNING,PIPELINES:clickLogs
     *                     Supported filter fields are NAME, STATUS, PIPELINES, CLUSTER.
     *                     Query will do an AND among filterBy fields.
     * @param entityTags <optional param> Return list of entities that have specified tags, separated by a comma.
     *                   Query will do AND on tag values.
     *                   Example: tags=consumer=consumer@xyz.com,owner=producer@xyz.com
     * @param entityOrderBy <optional param> Field by which results should be ordered.
     *                      Supports ordering by "name".
     * @param entitySortOrder <optional param> Valid options are "asc" and "desc"
     * @param entityOffset <optional param> Show results from the offset, used for pagination. Defaults to 0.
     * @param numEntities <optional param> Number of results to show per request, used for pagination. Only
     *                    integers > 0 are valid, Default is 10.
     * @param numInstanceResults <optional param> Number of recent instances to show per entity. Only integers > 0 are
     *                           valid, Default is 7.
     * @return Show entities along with summary of N instances for each entity.
     */
    @GET
    @Path("summary/{type}")
    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
    @Monitored(event = "summary")
    @Override
    public EntitySummaryResult getEntitySummary(
            @Dimension("type") @PathParam("type") final String type,
            @Dimension("cluster") @QueryParam("cluster") final String clusterName,
            @DefaultValue("") @QueryParam("start") final String startStr,
            @DefaultValue("") @QueryParam("end") final String endStr,
            @DefaultValue("") @QueryParam("fields") final String entityFields,
            @DefaultValue("") @QueryParam("filterBy") final String entityFilter,
            @DefaultValue("") @QueryParam("tags") final String entityTags,
            @DefaultValue("") @QueryParam("orderBy") final String entityOrderBy,
            @DefaultValue("asc") @QueryParam("sortOrder") final String entitySortOrder,
            @DefaultValue("0") @QueryParam("offset") final Integer entityOffset,
            @DefaultValue("10") @QueryParam("numResults") final Integer numEntities,
            @DefaultValue("7") @QueryParam("numInstances") final Integer numInstanceResults,
            @DefaultValue("") @QueryParam("doAs") final String doAsUser) {
        final String entityName = null;
        return new EntityProxy<EntitySummaryResult>(type, null, EntitySummaryResult.class) {
            @Override
            protected Set<String> getColosToApply() {
                Set<String> result = new HashSet<>();
                try {
                    Cluster cluster = EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
                    result.add(cluster.getColo());
                } catch (FalconException e) {
                    // ignore, just return blank result
                }
                return result;
            }

            @Override
            protected EntitySummaryResult doExecute(String colo) throws FalconException {
                EntitySummaryResult es = entityProxyUtil.getEntityManager(colo).invoke("getEntitySummary", type,
                        clusterName, startStr, endStr, entityFields, entityFilter, entityTags, entityOrderBy,
                        entitySortOrder, entityOffset, numEntities, numInstanceResults, doAsUser);
                return es;
            }
        }.execute();
    }

    /**
     * Get the name of the feed along with the location type(meta/data/stats) and cluster on which the given path
     * belongs to this feed.
     * @param type Valid option is feed.
     * @param path path of the instance for which you want to determine the feed
     *             Example: /data/project1/2014/10/10/23/ Path has to be the complete path and can't be a part of it.
     * @return Returns the name of the feed along with the location type(meta/data/stats) and cluster on which the given
     *         path belongs to this feed.
     */
    @GET
    @Path("lookup/{type}")
    @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
    @Monitored(event = "reverse-lookup")
    public FeedLookupResult reverseLookup(
            @Dimension("type") @PathParam("type") final String type,
            @Dimension("path") @QueryParam("path") final String path) {
        String entity = "DummyEntity"; // A dummy entity name to get around
        return new EntityProxy<FeedLookupResult>(type, entity, FeedLookupResult.class) {
            @Override
            protected Set<String> getColosToApply() {
                return getAllColos();
            }

            @Override
            protected FeedLookupResult doExecute(String colo) throws FalconException {
                return entityProxyUtil.getEntityManager(colo).invoke("reverseLookup", type, path);
            }
        }.execute();

    }
    //RESUME CHECKSTYLE CHECK ParameterNumberCheck


}
