// Copyright 2013 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	
	
	
	
	
)

type FloatString float64

func ( FloatString) () string {
	return strconv.FormatFloat(float64(), 'f', -1, 64)
}

func ( FloatString) () ([]byte, error) {
	return json.Marshal(.String())
}

func ( *FloatString) ( []byte) error {
	if len() < 2 || [0] != '"' || [len()-1] != '"' {
		return errors.New("float value must be a quoted string")
	}
	,  := strconv.ParseFloat(string([1:len()-1]), 64)
	if  != nil {
		return 
	}
	* = FloatString()
	return nil
}

type HistogramBucket struct {
	Boundaries int32
	Lower      FloatString
	Upper      FloatString
	Count      FloatString
}

func ( HistogramBucket) () ([]byte, error) {
	,  := json.Marshal(.Boundaries)
	if  != nil {
		return nil, 
	}
	,  := json.Marshal(.Lower)
	if  != nil {
		return nil, 
	}
	,  := json.Marshal(.Upper)
	if  != nil {
		return nil, 
	}
	,  := json.Marshal(.Count)
	if  != nil {
		return nil, 
	}
	return []byte(fmt.Sprintf("[%s,%s,%s,%s]", , , , )), nil
}

func ( *HistogramBucket) ( []byte) error {
	 := []interface{}{&.Boundaries, &.Lower, &.Upper, &.Count}
	 := len()
	if  := json.Unmarshal(, &);  != nil {
		return 
	}
	if  := len();  !=  {
		return fmt.Errorf("wrong number of fields: %d != %d", , )
	}
	return nil
}

func ( *HistogramBucket) ( *HistogramBucket) bool {
	return  ==  || (.Boundaries == .Boundaries && .Lower == .Lower && .Upper == .Upper && .Count == .Count)
}

func ( HistogramBucket) () string {
	var  strings.Builder
	 := .Boundaries == 1 || .Boundaries == 3
	 := .Boundaries == 0 || .Boundaries == 3
	if  {
		.WriteRune('[')
	} else {
		.WriteRune('(')
	}
	fmt.Fprintf(&, "%g,%g", .Lower, .Upper)
	if  {
		.WriteRune(']')
	} else {
		.WriteRune(')')
	}
	fmt.Fprintf(&, ":%v", .Count)
	return .String()
}

type HistogramBuckets []*HistogramBucket

func ( HistogramBuckets) ( HistogramBuckets) bool {
	if len() != len() {
		return false
	}

	for ,  := range  {
		if !.Equal([]) {
			return false
		}
	}
	return true
}

type SampleHistogram struct {
	Count   FloatString      `json:"count"`
	Sum     FloatString      `json:"sum"`
	Buckets HistogramBuckets `json:"buckets"`
}

func ( SampleHistogram) () string {
	return fmt.Sprintf("Count: %f, Sum: %f, Buckets: %v", .Count, .Sum, .Buckets)
}

func ( *SampleHistogram) ( *SampleHistogram) bool {
	return  ==  || (.Count == .Count && .Sum == .Sum && .Buckets.Equal(.Buckets))
}

type SampleHistogramPair struct {
	Timestamp Time
	// Histogram should never be nil, it's only stored as pointer for efficiency.
	Histogram *SampleHistogram
}

func ( SampleHistogramPair) () ([]byte, error) {
	if .Histogram == nil {
		return nil, errors.New("histogram is nil")
	}
	,  := json.Marshal(.Timestamp)
	if  != nil {
		return nil, 
	}
	,  := json.Marshal(.Histogram)
	if  != nil {
		return nil, 
	}
	return []byte(fmt.Sprintf("[%s,%s]", , )), nil
}

func ( *SampleHistogramPair) ( []byte) error {
	 := []interface{}{&.Timestamp, &.Histogram}
	 := len()
	if  := json.Unmarshal(, &);  != nil {
		return 
	}
	if  := len();  !=  {
		return fmt.Errorf("wrong number of fields: %d != %d", , )
	}
	if .Histogram == nil {
		return errors.New("histogram is null")
	}
	return nil
}

func ( SampleHistogramPair) () string {
	return fmt.Sprintf("%s @[%s]", .Histogram, .Timestamp)
}

func ( *SampleHistogramPair) ( *SampleHistogramPair) bool {
	return  ==  || (.Histogram.Equal(.Histogram) && .Timestamp.Equal(.Timestamp))
}