<commit_before>package ws.osiris.core

import java.util.regex.Pattern

/**
 * A segment in an HTTP route; a segment represents the part of a route between two slashes, for example the route
 * `/foo/bar` contains two segments, one for `foo` and one for `bar`.
 */
sealed class Segment {

    companion object {

        private val variableSegmentPattern = Pattern.compile("\\{\\w+}")

        fun create(pathPart: String): Segment =
            if (variableSegmentPattern.matcher(pathPart).matches()) {
                VariableSegment(pathPart.substring(1..pathPart.length - 2))
            } else {
                FixedSegment(pathPart)
            }
    }
}

/**
 * A [Segment] that corresponds to a section of the path with a fixed name; e.g. the path `/foo/bar` contains
 * two fixed segments with [pathPart] `foo` and `bar` respectively.
 */
data class FixedSegment(val pathPart: String) : Segment()

/**
 * A [Segment] that corresponds to a section of the path that matches a path variable; e.g. the path `/{foo}`
 * contains one variable segment with a [variableName] of `foo`.
 */
data class VariableSegment(val variableName: String) : Segment()

/**
 * Represents a route in the API or a subsection of it; used when building a tree of [RouteNode] instances
 * from a list if [Route] instances defined in an [Api].
 *
 * For example, a [Route] with a path `/foo/bar/baz` can have a corresponding [SubRoute] with paths `foo`,
 * `bar` and `baz`. As the tree of route nodes is created, [SubRoute] instances will be created with paths
 * of `foo`, `bar` and finally just `foo`.
 */
internal class SubRoute<T : ComponentsProvider> private constructor(val route: Route<T>, val segments: List<Segment>) {

    constructor(route: Route<T>) : this(route, segments(route.path))

    companion object {
        private fun segments(path: String): List<Segment> =
            path.split('/').map { it.trim() }.filter { it.isNotEmpty() }.map { Segment.create(it) }
    }

    fun isEmpty(): Boolean = segments.isEmpty()

    fun head(): Segment = when {
        isEmpty() -> throw IllegalStateException("Cannot take the head of an empty sub-route")
        else -> segments[0]
    }

    fun tail(): SubRoute<T> = when {
        isEmpty() -> throw IllegalStateException("Cannot take the tail of an empty sub-route")
        else -> SubRoute(route, segments.slice(1 until segments.size))
    }

    override fun toString(): String {
        return "SubRoute(route=$route, segments=$segments)"
    }
}

/**
 * A node in the tree of routes that make up an API.
 *
 * The routes in an API can be represented as a tree. The route at the base of the API `/` is represented by
 * the `RouteNode` at the root of the tree. Each node in the tree corresponds to one section of a route.
 *
 * For example, consider an API with the following routes:
 * ```
 * /foo
 * /foo/bar
 * /foo/baz
 * /qux
 * ```
 * It is represented by the following tree:
 * ```
 * /
 *  |- foo
 *  |   |- bar
 *  |   `- baz
 *  `- qux
 * ```
 */
sealed class RouteNode<T : ComponentsProvider>(

    /** The name of the node; For a fixed node this is the path part, for a variable node it's the variable name. */
    val name: String,

    /** Handlers (and their associated [Auth]) keyed by the HTTP method they handle */
    val handlers: Map<HttpMethod, Pair<RequestHandler<T>, Auth?>>,

    /** The fixed node children of this node, keyed by their path part. */
    val fixedChildren: Map<String, RouteNode<T>>,

    /** The variable node that is a child of this node; has a variable path part, e.g. `{foo}`. */
    val variableChild: VariableRouteNode<T>?
) {

    companion object {

        // TODO add a CORS filter at the start of the filters.
        //  this only needs to be done for routes where cors == true
        //  maybe create two lists, one for CORS routes and on for others
        //  also need to create an OPTIONS handler for CORS routes where the user doesn't
<commit_msg>Delete redundant TODO<commit_after>package ws.osiris.core

import java.util.regex.Pattern

/**
 * A segment in an HTTP route; a segment represents the part of a route between two slashes, for example the route
 * `/foo/bar` contains two segments, one for `foo` and one for `bar`.
 */
sealed class Segment {

    companion object {

        private val variableSegmentPattern = Pattern.compile("\\{\\w+}")

        fun create(pathPart: String): Segment =
            if (variableSegmentPattern.matcher(pathPart).matches()) {
                VariableSegment(pathPart.substring(1..pathPart.length - 2))
            } else {
                FixedSegment(pathPart)
            }
    }
}

/**
 * A [Segment] that corresponds to a section of the path with a fixed name; e.g. the path `/foo/bar` contains
 * two fixed segments with [pathPart] `foo` and `bar` respectively.
 */
data class FixedSegment(val pathPart: String) : Segment()

/**
 * A [Segment] that corresponds to a section of the path that matches a path variable; e.g. the path `/{foo}`
 * contains one variable segment with a [variableName] of `foo`.
 */
data class VariableSegment(val variableName: String) : Segment()

/**
 * Represents a route in the API or a subsection of it; used when building a tree of [RouteNode] instances
 * from a list if [Route] instances defined in an [Api].
 *
 * For example, a [Route] with a path `/foo/bar/baz` can have a corresponding [SubRoute] with paths `foo`,
 * `bar` and `baz`. As the tree of route nodes is created, [SubRoute] instances will be created with paths
 * of `foo`, `bar` and finally just `foo`.
 */
internal class SubRoute<T : ComponentsProvider> private constructor(val route: Route<T>, val segments: List<Segment>) {

    constructor(route: Route<T>) : this(route, segments(route.path))

    companion object {
        private fun segments(path: String): List<Segment> =
            path.split('/').map { it.trim() }.filter { it.isNotEmpty() }.map { Segment.create(it) }
    }

    fun isEmpty(): Boolean = segments.isEmpty()

    fun head(): Segment = when {
        isEmpty() -> throw IllegalStateException("Cannot take the head of an empty sub-route")
        else -> segments[0]
    }

    fun tail(): SubRoute<T> = when {
        isEmpty() -> throw IllegalStateException("Cannot take the tail of an empty sub-route")
        else -> SubRoute(route, segments.slice(1 until segments.size))
    }

    override fun toString(): String {
        return "SubRoute(route=$route, segments=$segments)"
    }
}

/**
 * A node in the tree of routes that make up an API.
 *
 * The routes in an API can be represented as a tree. The route at the base of the API `/` is represented by
 * the `RouteNode` at the root of the tree. Each node in the tree corresponds to one section of a route.
 *
 * For example, consider an API with the following routes:
 * ```
 * /foo
 * /foo/bar
 * /foo/baz
 * /qux
 * ```
 * It is represented by the following tree:
 * ```
 * /
 *  |- foo
 *  |   |- bar
 *  |   `- baz
 *  `- qux
 * ```
 */
sealed class RouteNode<T : ComponentsProvider>(

    /** The name of the node; For a fixed node this is the path part, for a variable node it's the variable name. */
    val name: String,

    /** Handlers (and their associated [Auth]) keyed by the HTTP method they handle */
    val handlers: Map<HttpMethod, Pair<RequestHandler<T>, Auth?>>,

    /** The fixed node children of this node, keyed by their path part. */
    val fixedChildren: Map<String, RouteNode<T>>,

    /** The variable node that is a child of this node; has a variable path part, e.g. `{foo}`. */
    val variableChild: VariableRouteNode<T>?
) {

    companion object {

{'fraction_non_alphanumeric': 0.11652903394940359, 'fraction_numerical': 0.0010486302267662866, 'mean_word_length': 2.943152454780362, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5441045', 'n_tokens_mistral': 2220, 'n_tokens_neox': 2166, 'n_words': 908}