// Copyright 2017, OpenCensus 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 view

import (
	"sort"

	"go.opencensus.io/internal/tagencoding"
	"go.opencensus.io/tag"
)

type collector struct {
	// signatures holds the aggregations values for each unique tag signature
	// (values for all keys) to its aggregator.
	signatures map[string]AggregationData
	// Aggregation is the description of the aggregation to perform for this
	// view.
	a *Aggregation
}

func (c *collector) addSample(s string, v float64) {
	aggregator, ok := c.signatures[s]
	if !ok {
		aggregator = c.a.newData()
		c.signatures[s] = aggregator
	}
	aggregator.addSample(v)
}

func (c *collector) collectedRows(keys []tag.Key) []*Row {
	var rows []*Row
	for sig, aggregator := range c.signatures {
		tags := decodeTags([]byte(sig), keys)
		row := &Row{tags, aggregator}
		rows = append(rows, row)
	}
	return rows
}

func (c *collector) clearRows() {
	c.signatures = make(map[string]AggregationData)
}

// encodeWithKeys encodes the map by using values
// only associated with the keys provided.
func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte {
	vb := &tagencoding.Values{
		Buffer: make([]byte, len(keys)),
	}
	for _, k := range keys {
		v, _ := m.Value(k)
		vb.WriteValue([]byte(v))
	}
	return vb.Bytes()
}

// decodeTags decodes tags from the buffer and
// orders them by the keys.
func decodeTags(buf []byte, keys []tag.Key) []tag.Tag {
	vb := &tagencoding.Values{Buffer: buf}
	var tags []tag.Tag
	for _, k := range keys {
		v := vb.ReadValue()
		if v != nil {
			tags = append(tags, tag.Tag{Key: k, Value: string(v)})
		}
	}
	vb.ReadIndex = 0
	sort.Slice(tags, func(i, j int) bool { return tags[i].Key.Name() < tags[j].Key.Name() })
	return tags
}
