/**
   * Ensures all parameters are valid for the Recently Created Chart
   *
   * @param queryString a filter id (starts with "filter-") or project id (starts with "project-").
   * @param dateField The date field to calculate chart against
   * @param days The number of days previous to go back for. Must be positive.
   * @param periodName The name of the period. See - {@link
   *     com.atlassian.jira.charts.ChartFactory.PeriodName}
   * @return a Collection of {@link com.atlassian.jira.rest.v1.model.errors.ValidationError}. Or
   *     empty list if no errors.
   */
  @GET
  @Path("/validate")
  public Response validateChart(
      @QueryParam(QUERY_STRING) String queryString,
      @QueryParam(DATE_FIELD) @DefaultValue("created") String dateField,
      @QueryParam(DAYS) @DefaultValue("30") final String days,
      @QueryParam(PERIOD_NAME) @DefaultValue("daily") final String periodName) {
    final Collection<ValidationError> errors = new ArrayList<ValidationError>();

    getSearchRequestAndValidate(queryString, errors, new HashMap<String, Object>());
    final ChartFactory.PeriodName period =
        resourceDateValidator.validatePeriod(PERIOD_NAME, periodName, errors);
    resourceDateValidator.validateDaysPrevious(DAYS, period, days, errors);
    validateDateField(dateField, errors);

    return createValidationResponse(errors);
  }
  /**
   * Generate a Time Since Chart Chart and returns a simple bean containing all relevent information
   *
   * @param request The current HTTPRequest. Needed for url generation
   * @param queryString a filter id (starts with "filter-") or project id (starts with "project-")or
   *     jql (starts with "jql-")
   * @param dateField The date field to calculate chart against
   * @param days The number of days previous to go back for. Must be positive.
   * @param periodName The name of the period. See - {@link
   *     com.atlassian.jira.charts.ChartFactory.PeriodName}
   * @param isCumulative Whether or not previous column is added the current column to give a total
   *     for the period.
   * @param width the width of the chart in pixels (defaults to 400px)
   * @param height the height of the chart in pixels (defaults to 250px)
   * @return a {@link com.atlassian.jira.gadgets.system.TimeSinceChartResource.TimeSinceChart} if
   *     all params validated else a Collection of {@link
   *     com.atlassian.jira.rest.v1.model.errors.ValidationError}
   */
  @GET
  @Path("/generate")
  public Response generateChart(
      @Context HttpServletRequest request,
      @QueryParam(QUERY_STRING) String queryString,
      @QueryParam(DATE_FIELD) @DefaultValue("created") String dateField,
      @QueryParam(DAYS) @DefaultValue("30") final String days,
      @QueryParam(PERIOD_NAME) @DefaultValue("daily") final String periodName,
      @QueryParam(IS_CUMULATIVE) @DefaultValue("true") final boolean isCumulative,
      @QueryParam(WIDTH) @DefaultValue("450") final int width,
      @QueryParam(HEIGHT) @DefaultValue("300") final int height,
      @QueryParam(INLINE) @DefaultValue("false") final boolean inline) {
    final Collection<ValidationError> errors = new ArrayList<ValidationError>();

    final User user = authenticationContext.getLoggedInUser();
    final SearchRequest searchRequest;

    Map<String, Object> params = new HashMap<String, Object>();

    // validate input
    searchRequest = getSearchRequestAndValidate(queryString, errors, params);
    final ChartFactory.PeriodName period =
        resourceDateValidator.validatePeriod(PERIOD_NAME, periodName, errors);
    final int validatedDays =
        resourceDateValidator.validateDaysPrevious(DAYS, period, days, errors);
    final Field field = validateDateField(dateField, errors);

    if (!errors.isEmpty()) {
      return createErrorResponse(errors);
    }

    final ChartFactory.ChartContext context =
        new ChartFactory.ChartContext(user, searchRequest, width, height, inline);
    try {
      final Chart chart =
          chartFactory.generateTimeSinceChart(
              context, validatedDays, period, isCumulative, field.getId());

      final String location = chart.getLocation();
      final String title = getFilterTitle(params);
      final String filterUrl = getFilterUrl(params);
      final Integer issueCount = (Integer) chart.getParameters().get(NUM_ISSUES);
      final String imageMap = chart.getImageMap();
      final String imageMapName = chart.getImageMapName();
      final String chartFilterUrl = (String) chart.getParameters().get("chartFilterUrl");
      final boolean isProject = params.containsKey("project");
      final TimeSinceChart timeSinceChart =
          new TimeSinceChart(
              location,
              title,
              filterUrl,
              imageMap,
              imageMapName,
              issueCount,
              field.getName(),
              width,
              height,
              chartFilterUrl,
              isProject,
              chart.getBase64Image());

      return Response.ok(timeSinceChart).cacheControl(NO_CACHE).build();
    } catch (SearchUnavailableException e) {
      if (!e.isIndexingEnabled()) {
        return createIndexingUnavailableResponse(createIndexingUnavailableMessage());
      } else {
        throw e;
      }
    }
  }