
import Foundation
/**
 A multi-value metrics aggregation that computes stats over numeric values
 extracted from the aggregated documents. These values can be extracted either
 from specific numeric fields in the documents, or be generated by a provided
 script.

 The stats that are returned consist of: min, max, sum, count and avg.

 [More information](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html)
 */
public struct StatsAggregation: Aggregation {
    /// :nodoc:
    public static var typeKey = AggregationResponseMap.stats
    
    /// :nodoc:
    public var name: String
    
    /// :nodoc:
    public let field: String?
    
    /// :nodoc:
    public let script: Script?
    
    /// :nodoc:
    public let missing: Int?
    
    enum CodingKeys: String, CodingKey {
        case field
        case script
        case missing
    }
    
    /// Creates a [stats](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html) aggregation
    ///
    /// - Parameters:
    ///   - name: The aggregation name
    ///   - field: The field to perform the aggregation over
    ///   - script: A script used to calculate the values
    ///   - missing: Defines how documents that are missing a value should be treated
    public init(
        name: String,
        field: String? = nil,
        script: Script? = nil,
        missing: Int? = nil
        ) {
        self.name = name
        self.field = field
        self.script = script
        self.missing = missing
    }
    
    /// :nodoc:
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: DynamicKey.self)
        var valuesContainer = container.nestedContainer(keyedBy: CodingKeys.self, forKey: DynamicKey(stringValue: type(of: self).typeKey.rawValue)!)
        try valuesContainer.encodeIfPresent(field, forKey: .field)
        try valuesContainer.encodeIfPresent(script, forKey: .script)
        try valuesContainer.encodeIfPresent(missing, forKey: .missing)
    }
}
