/*
   * Return the SelectionListValue's associated with a single ReportParameter
   * that is specified by its id. This endpoint can be tested with:
   *
   * $ mvn clean spring-boot:run $ curl -i -H "Accept: application/json;v=1"
   * -X GET \
   * http://localhost:8080/rest/reportParameters/0955ab6e-6ce6-4b90-a60c-
   * aa0548e4d358/selectionListValues\ ?expand=selectionListValues
   *
   * @Transactional is used to avoid org.hibernate.LazyInitializationException
   * being thrown when evaluating reportParameter.getSelectionListValues().
   */
  @Transactional
  @Path("/{id}" + ResourcePath.SELECTIONLISTVALUES_PATH)
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  @PreAuthorize("hasAuthority('" + Authority.AUTHORITY_NAME_MANAGE_REPORTS + "')")
  public SelectionListValueCollectionResource getSelectionListValuesByReportParameterId(
      @PathParam("id") final UUID id,
      @HeaderParam("Accept") final String acceptHeader,
      @QueryParam(ResourcePath.EXPAND_QP_NAME) final List<String> expand,
      @QueryParam(ResourcePath.SHOWALL_QP_NAME) final List<String> showAll,
      @QueryParam(ResourcePath.PARENTPARAMVALUE_QP_NAME) final List<String> parentParamValues,
      @Context final UriInfo uriInfo)
      throws RptdesignOpenFromStreamException, BirtException {
    Map<String, List<String>> queryParams = new HashMap<>();
    queryParams.put(ResourcePath.EXPAND_QP_KEY, expand);
    queryParams.put(ResourcePath.SHOWALL_QP_KEY, showAll);
    queryParams.put(ResourcePath.PARENTPARAMVALUE_QP_NAME, parentParamValues);
    RestApiVersion apiVersion = RestUtils.extractAPIVersion(acceptHeader, RestApiVersion.v1);

    ReportParameter reportParameter = reportParameterRepository.findOne(id);
    RestUtils.ifNullThen404(
        reportParameter, ReportParameter.class, "reportParameterId", id.toString());

    /*
     * Create a SelectionListValueCollectionResource to represent the
     * selection list values. If the selection list is dynamic, i.e., it
     * must be generated by running a query that is represented by a data
     * source specified in the rptdesign file, then it is necessary to use
     * the BIRT API to request these values.
     *
     * If, on the other hand, the selection list is static or there is no
     * selection list at all, then it is a simple matter of creating a
     * SelectionListValueCollectionResource from SelectionListValue entities
     * stored in the report server database.
     */
    SelectionListValueCollectionResource selectionListValueCollectionResource = null;
    if (reportParameter.getSelectionListType().equals(IParameterDefn.SELECTION_LIST_DYNAMIC)) {
      /*
       * The selection list is *dynamic*, i.e., it is defined by some sort
       * of database query, instead of consisting of static values that
       * were chosen when the rptdesign file was created.
       */
      try {
        logger.info("parentParamValues = {}", parentParamValues);
        String rptdesign = reportParameter.getReportVersion().getRptdesign();

        List<SelectionListValue> selectionListValues =
            reportParameterService.getDynamicSelectionListValues(
                reportParameter, parentParamValues, rptdesign, uriInfo, queryParams, apiVersion);

        /*
         * Note: The SelectionListValue entities in the list
         *       "selectionListValues" will have
         *       selectionListValueId = null because they were not
         *       retrieved from the database.
         *
         *       In addition, "createdOn" for each entity will be the
         *       datetime when the entity object was CONSTRUCTED.
         */
        selectionListValueCollectionResource =
            new SelectionListValueCollectionResource(
                selectionListValues,
                SelectionListValue.class,
                AbstractBaseResource.createHref(
                    uriInfo, ReportParameter.class, reportParameter.getReportParameterId(), null),
                ResourcePath.SELECTIONLISTVALUES_PATH,
                uriInfo,
                queryParams,
                apiVersion);

      } catch (DynamicSelectionListKeyException e) {
        throw new RestApiException(
            RestError.FORBIDDEN_DYN_SEL_LIST_PARENT_KEY_COUNT, e.getMessage());
      }

    } else {
      /*
       * Either the selection list is STATIC or there is NO selection list
       * at all. It is a simple matter of returning a
       * SelectionListValueCollectionResource based on SelectionListValue
       * entities stored in the report server database that are linked to
       * the specified report parameter.
       */
      selectionListValueCollectionResource =
          new SelectionListValueCollectionResource(
              reportParameter, uriInfo, queryParams, apiVersion);
    }
    return selectionListValueCollectionResource;
  }