<commit_before>//
//  TypedQuery.swift
//  Contentful
//
//  Created by <NAME> on 12.10.17.
//  Copyright © 2017 Contentful GmbH. All rights reserved.
//

import Foundation

/// A concrete implementation of ChainableQuery which can be used to make queries on `/entries/`
/// or `/entries`. All methods from ChainableQuery are available.
public class Query: ResourceQuery, EntryQuery {

    public static var any: Query {
        return Query()
    }
}

/// An additional query to filter by the properties of linked objects when searching on references.
/// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
/// and see the init<LinkType: EntryDecodable>(whereLinkAt fieldNameForLink: String, matches filterQuery: FilterQuery<LinkType>? = nil) methods
/// on QueryOn for example usage.
public final class LinkQuery<EntryType>: AbstractQuery where EntryType: EntryDecodable & FieldKeysQueryable {

    /// The parameters dictionary that are converted to `URLComponents` (HTTP parameters/arguments) on the HTTP URL. Useful for debugging.
    public var parameters: [String: String] = [String: String]()

    // Different function name to ensure inner call to where(valueAtKeyPath:operation:) doesn't recurse.
    private static func with(valueAtKeyPath keyPath: String, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        let filterQuery = LinkQuery<EntryType>.where(valueAtKeyPath: keyPath, operation)
        filterQuery.propertyName = keyPath
        filterQuery.operation = operation
        return filterQuery
    }

    /// Static method for creating a new LinkQuery with an operation. This variation for initializing guarantees
    /// correct query contruction by utilizing the associated Fields CodingKeys type required by ResourceQueryable on the type you are linking to.
    ///
    /// Example usage:
    ///
    /// ```
    /// let linkQuery = LinkQuery<Cat>.where(field: .name, .matches("Happy Cat"))
    /// let query = QueryOn<Cat>(whereLinkAtField: .bestFriend, matches: linkQuery)
    /// client.fetchArray(of: Cat.self, matching: query) { (result: Result<ArrayResponse<Cat>>) in
    ///     switch result {
    ///     case .success(let arrayResponse):
    ///         let cats = arrayResponse.items
    ///         // Do stuff with cats.
    ///     case .failure(let error):
    ///         print(error)
    ///     }
    /// }
    /// ```
    /// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
    ///
    /// - Parameters:
    ///   - field: The member of the `FieldKeys` type associated with your type conforming to `EntryDecodable & ResourceQueryable`
    ///            that you are performing your search on reference against.
    ///   - operation: The query operation used in the query.
    /// - Returns: A newly initialized `QueryOn` query.
    public static func `where`(field: EntryType.FieldKeys, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        return LinkQuery<EntryType>.with(valueAtKeyPath: "fields.\(field.stringValue)", operation)
    }

    /// Static method for creating a new LinkQuery with an operation. This variation for initializing guarantees
    /// correct query contruction by utilizing the associated Sys CodingKeys type required by ResourceQueryable on the type you are linking to.
    ///
    /// Example usage:
    ///
    /// ```
    /// let linkQuery = LinkQuery<Cat>.where(sys: .id, .matches("happycat"))
    /// let query = QueryOn<Cat>(whereLinkAtField: .bestFriend, matches: linkQuery)
    /// client.fetchArray(of: Cat.self, matching: query) { (result: Result<ArrayResponse<Cat>>) in
    ///     switch result {
    ///     case .success(let arrayResponse):
    ///         let cats = arrayResponse.items
    ///         // Do stuff with cats.
    ///     case .failure(let error):
    ///         print(error)
    ///     }
    /// }
    /// ```
    /// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
    ///
    /// - Parameters:
    ///   - sys: The member of the `Sys.CodingKeys` type associated with your type conforming to `EntryDecodable & ResourceQueryable`
    ///            that you are performing your search on reference against.
    ///   - operation: The query operation used in the query.
    /// - Returns: A newly initialized `QueryOn` query.
    public static func `where`(sys key: Sys.CodingKeys, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        return LinkQuery<EntryType>.with(valueAtKeyPath: "sys.\(key.stringValue)", operation)
    }

    /// Designated initializer for FilterQuery.
    public init() {
        self.parameters = [String: String]()
    }

    // MARK: FilterQuery<EntryType>.Private

    fileprivate var operation: Query.Operation!
    fileprivate var propertyName: String?
}

/// A concrete implementation of EntryQuery which requires that a model class conforming to `EntryType`
/// be passed in as a generic parameter.
/// The "content_type" parameter of the query will be set using the `contentTypeID` of the generic parameter conforming<commit_msg>Update docs<commit_after>//
//  TypedQuery.swift
//  Contentful
//
//  Created by <NAME> on 12.10.17.
//  Copyright © 2017 Contentful GmbH. All rights reserved.
//

import Foundation

/// A concrete implementation of ChainableQuery which can be used to make queries on `/entries/`
/// or `/entries`. All methods from ChainableQuery are available.
public class Query: ResourceQuery, EntryQuery {

    public static var any: Query {
        return Query()
    }
}

/// An additional query to filter by the properties of linked objects when searching on references.
/// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
/// and see the init<LinkType: EntryDecodable>(whereLinkAt fieldNameForLink: String, matches filterQuery: FilterQuery<LinkType>? = nil) methods
/// on QueryOn for example usage.
public final class LinkQuery<EntryType>: AbstractQuery where EntryType: EntryDecodable & FieldKeysQueryable {

    /// The parameters dictionary that are converted to `URLComponents` (HTTP parameters/arguments) on the HTTP URL. Useful for debugging.
    public var parameters: [String: String] = [String: String]()

    // Different function name to ensure inner call to where(valueAtKeyPath:operation:) doesn't recurse.
    private static func with(valueAtKeyPath keyPath: String, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        let filterQuery = LinkQuery<EntryType>.where(valueAtKeyPath: keyPath, operation)
        filterQuery.propertyName = keyPath
        filterQuery.operation = operation
        return filterQuery
    }

    /// Static method for creating a new LinkQuery with an operation. This variation for initializing guarantees
    /// correct query contruction by utilizing the associated Fields CodingKeys type required by ResourceQueryable on the type you are linking to.
    ///
    /// Example usage:
    ///
    /// ```
    /// let linkQuery = LinkQuery<Cat>.where(field: .name, .matches("Happy Cat"))
    /// let query = QueryOn<Cat>(whereLinkAtField: .bestFriend, matches: linkQuery)
    /// client.fetchArray(of: Cat.self, matching: query) { (result: Result<ArrayResponse<Cat>>) in
    ///     switch result {
    ///     case .success(let arrayResponse):
    ///         let cats = arrayResponse.items
    ///         // Do stuff with cats.
    ///     case .failure(let error):
    ///         print(error)
    ///     }
    /// }
    /// ```
    /// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
    ///
    /// - Parameters:
    ///   - field: The member of the `FieldKeys` type associated with your type conforming to `EntryDecodable & ResourceQueryable`
    ///            that you are performing your search on reference against.
    ///   - operation: The query operation used in the query.
    /// - Returns: A newly initialized `QueryOn` query.
    public static func `where`(field: EntryType.FieldKeys, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        return LinkQuery<EntryType>.with(valueAtKeyPath: "fields.\(field.stringValue)", operation)
    }

    /**
     Static method for creating a new LinkQuery with an operation. This variation for initializing guarantees
     correct query contruction by utilizing the associated Sys CodingKeys type required by ResourceQueryable on
     the type you are linking to.

     Example usage:
     ```
     let linkQuery = LinkQuery<Cat>.where(sys: .id, .matches("happycat"))
     let query = QueryOn<Cat>(whereLinkAtField: .bestFriend, matches: linkQuery)
     client.fetchArray(of: Cat.self, matching: query) { (result: Result<ArrayResponse<Cat>>) in
         switch result {
         case .success(let arrayResponse):
             let cats = arrayResponse.items
             // Do stuff with cats.
         case .failure(let error):
             print(error)
         }
     }
     ```

     See: [Search on references](https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references)

    - Parameters:
        - sys: The member of the `Sys.CodingKeys` type associated with your type conforming
            to `EntryDecodable & ResourceQueryable` that you are performing your search on reference against.
        - operation: The query operation used in the query.
        - Returns: A newly initialized `QueryOn` query.
    */
    public static func `where`(sys key: Sys.CodingKeys, _ operation: Query.Operation) -> LinkQuery<EntryType> {
        return LinkQuery<EntryType>.with(valueAtKeyPath: "sys.\(key.stringValue)", operation)
    }

    /// Designated initializer for FilterQuery.
    public init() {
        self.parameters = [String: String]()
    }

    // MARK: FilterQuery<EntryType>.Private

    fileprivate var operation: Query.Operation!
    fileprivate var propertyName: String?
}

/// A concrete implementation of EntryQuery which requires that a model class conforming to `EntryType`
/// be passed in as a generic parameter.
/// The "content_type" parameter of the query will be set using the `contentTypeID` of the generic parameter conforming
{'fraction_non_alphanumeric': 0.1117596402258157, 'fraction_numerical': 0.001913692469620132, 'mean_word_length': 2.891288160833954, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 52, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, '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': '5982795', 'n_tokens_mistral': 2787, 'n_tokens_neox': 2722, 'n_words': 916}