class BlockController {

    @Path("/")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "The API returns Block information",
        description = "The API returns Block information with transaction info depending on specified params",
        tags = {"block"},
        responses = {
            @ApiResponse(responseCode = "200", description = "Successful execution",
                content = @Content(mediaType = "application/json",
                    schema = @Schema(implementation = BlockDTO.class)))
        })
    @PermitAll
    public Response getBlock(
        @Parameter(description = "Block id (optional, default is last block)",
            schema = @Schema(implementation = Long.class, description="Block id (optional, default is last block"))
            @QueryParam("block") LongParameter blockId,
        @Parameter(description = "The block height (optional, default is last block).")
            @QueryParam("height") @DefaultValue("-1") @ValidBlockchainHeight int height,
        @Parameter(description = "The earliest block (in seconds since the genesis block) to retrieve (optional)." )
            @QueryParam("timestamp") @DefaultValue("-1") @ValidTimestamp int timestamp,
        @Parameter(description = "Include transactions detail info" )
            @QueryParam("includeTransactions") @DefaultValue("false") boolean includeTransactions,
        @Parameter(description = "Include phased transactions detail info" )
            @QueryParam("includeExecutedPhased") @DefaultValue("false") boolean includeExecutedPhased
    ) {
        ResponseBuilder response = ResponseBuilder.startTiming();
        log.trace("Started getBlock : \t blockId={}, height={}, timestamp={}, includeTransactions={}, includeExecutedPhased={}",
            blockId, height, timestamp, includeTransactions, includeExecutedPhased);
        Block blockData;
        if (blockId != null && blockId.get() != 0) {
            blockData = blockchain.getBlock(blockId.get());
        } else if (height > 0) {
            if (height > blockchain.getHeight()) {
                String errorMessage = String.format("Requested height in bigger when actual height: %s", height);
                log.warn(errorMessage);
                return response.error(ApiErrors.INCORRECT_PARAM, "height", height).build();
            }
            blockData = blockchain.getBlockAtHeight(height);
        } else if (timestamp > 0) {
            blockData = blockchain.getLastBlock(timestamp);
        } else {
            blockData = blockchain.getLastBlock();
        }
        if (blockData == null) {
            return response.error(ApiErrors.UNKNOWN_VALUE, "block", blockData).build();
        }
        blockConverter.setAddTransactions(includeTransactions);
        blockConverter.setAddPhasedTransactions(includeExecutedPhased);
        BlockDTO dto = blockConverter.convert(blockData);
        log.trace("getBlock result: {}", dto);
        return response.bind(dto).build();
    }

    @Inject public  BlockController(Blockchain blockchain, BlockConverter blockConverter,
                           FirstLastIndexParser indexParser, TimeService timeService);

}