class PublicApiHandler {

    @GET
    @Path("integrations/{env}/export.zip")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    @SuppressWarnings("JdkObsolete")
    public Response exportResources(@NotNull @PathParam("env") @Parameter(required = true) String environment,
                                    @QueryParam("all") @Parameter boolean exportAll,
                                    @QueryParam("ignoreTimestamp") @Parameter boolean ignoreTimestamp) throws IOException {

        // validate environment
        EnvironmentHandler.validateEnvironment("environment", environment);
        final Environment env = environmentHandler.getEnvironment(environment);

        // lookup integrations to export for this environment
        final ListResult<Integration> integrations;

        // export all integrations ignoring any missing/existing tags?
        final String envId = env.getId().get();
        if (exportAll) {

            integrations = dataMgr.fetchAll(Integration.class);

            // tag all integrations for export
            @SuppressWarnings("JdkObsolete") Date taggedAt = new Date();
            integrations.getItems().forEach(i -> {
                final HashMap<String, ContinuousDeliveryEnvironment> state = new HashMap<>(i.getContinuousDeliveryState());
                EnvironmentHandler.createOrUpdateTag(state, envId, taggedAt);
                dataMgr.update(i.builder().continuousDeliveryState(state).build());
            });

            LOG.debug("Exporting ALL ({}) integrations for environment {} at {} ...", integrations.getItems().size(), environment, taggedAt);
        } else {

            // export integrations freshly tagged or tagged after last export
            integrations = dataMgr.fetchAll(Integration.class, listResult -> listResult.getItems().stream().filter(i -> {

                boolean result = ignoreTimestamp;
                final Map<String, ContinuousDeliveryEnvironment> map = i.getContinuousDeliveryState();
                final ContinuousDeliveryEnvironment cdEnv = map.get(envId);
                if (!ignoreTimestamp && cdEnv != null) {
                    final Date taggedAt = cdEnv.getLastTaggedAt();
                    final Date exportedAt = cdEnv.getLastExportedAt().orElse(null);
                    result = exportedAt == null || exportedAt.before(taggedAt);
                }

                return result;
            }).collect(ListResult.collector()).build());

            LOG.debug("Exporting ({}) integrations for environment {} ...", integrations.getItems().size(), environment);
        }

        final List<String> ids = integrations.getItems().stream()
            .map(integration -> integration.getId().get())
            .collect(Collectors.toList());

        if (ids.isEmpty()) {
            return Response.status(Response.Status.NO_CONTENT.getStatusCode(), "No integrations to export").build();
        }

        @SuppressWarnings("JdkObsolete") final Date exportedAt = new Date();
        final StreamingOutput output = handler.export(ids);

        // update lastExportedAt
        environmentHandler.updateCDEnvironments(integrations.getItems(), envId, exportedAt, b -> b.lastExportedAt(exportedAt));

        LOG.debug("Exported ({}) integrations for environment {}", ids.size(), environment);
        return Response.ok(output).build();
    }

    protected  PublicApiHandler(DataManager dataMgr, EncryptionComponent encryptionComponent,
        IntegrationDeploymentHandler deploymentHandler, ConnectionHandler connectionHandler,
        MonitoringProvider monitoringProvider, EnvironmentHandler environmentHandler,
        IntegrationSupportHandler handler, IntegrationHandler integrationHandler);

}