// 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 (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"sort"
	"sync/atomic"
	"time"

	"go.opencensus.io/stats"
	"go.opencensus.io/tag"
)

// View allows users to aggregate the recorded stats.Measurements.
// Views need to be passed to the Register function to be before data will be
// collected and sent to Exporters.
type View struct {
	Name        string // Name of View. Must be unique. If unset, will default to the name of the Measure.
	Description string // Description is a human-readable description for this view.

	// TagKeys are the tag keys describing the grouping of this view.
	// A single Row will be produced for each combination of associated tag values.
	TagKeys []tag.Key

	// Measure is a stats.Measure to aggregate in this view.
	Measure stats.Measure

	// Aggregation is the aggregation function tp apply to the set of Measurements.
	Aggregation *Aggregation
}

// WithName returns a copy of the View with a new name. This is useful for
// renaming views to cope with limitations placed on metric names by various
// backends.
func (v *View) WithName(name string) *View {
	vNew := *v
	vNew.Name = name
	return &vNew
}

// same compares two views and returns true if they represent the same aggregation.
func (v *View) same(other *View) bool {
	if v == other {
		return true
	}
	if v == nil {
		return false
	}
	return reflect.DeepEqual(v.Aggregation, other.Aggregation) &&
		v.Measure.Name() == other.Measure.Name()
}

// ErrNegativeBucketBounds error returned if histogram contains negative bounds.
//
// Deprecated: this should not be public.
var ErrNegativeBucketBounds = errors.New("negative bucket bounds not supported")

// canonicalize canonicalizes v by setting explicit
// defaults for Name and Description and sorting the TagKeys
func (v *View) canonicalize() error {
	if v.Measure == nil {
		return fmt.Errorf("cannot register view %q: measure not set", v.Name)
	}
	if v.Aggregation == nil {
		return fmt.Errorf("cannot register view %q: aggregation not set", v.Name)
	}
	if v.Name == "" {
		v.Name = v.Measure.Name()
	}
	if v.Description == "" {
		v.Description = v.Measure.Description()
	}
	if err := checkViewName(v.Name); err != nil {
		return err
	}
	sort.Slice(v.TagKeys, func(i, j int) bool {
		return v.TagKeys[i].Name() < v.TagKeys[j].Name()
	})
	sort.Float64s(v.Aggregation.Buckets)
	for _, b := range v.Aggregation.Buckets {
		if b < 0 {
			return ErrNegativeBucketBounds
		}
	}
	// drop 0 bucket silently.
	v.Aggregation.Buckets = dropZeroBounds(v.Aggregation.Buckets...)

	return nil
}

func dropZeroBounds(bounds ...float64) []float64 {
	for i, bound := range bounds {
		if bound > 0 {
			return bounds[i:]
		}
	}
	return []float64{}
}

// viewInternal is the internal representation of a View.
type viewInternal struct {
	view       *View  // view is the canonicalized View definition associated with this view.
	subscribed uint32 // 1 if someone is subscribed and data need to be exported, use atomic to access
	collector  *collector
}

func newViewInternal(v *View) (*viewInternal, error) {
	return &viewInternal{
		view:      v,
		collector: &collector{make(map[string]AggregationData), v.Aggregation},
	}, nil
}

func (v *viewInternal) subscribe() {
	atomic.StoreUint32(&v.subscribed, 1)
}

func (v *viewInternal) unsubscribe() {
	atomic.StoreUint32(&v.subscribed, 0)
}

// isSubscribed returns true if the view is exporting
// data by subscription.
func (v *viewInternal) isSubscribed() bool {
	return atomic.LoadUint32(&v.subscribed) == 1
}

func (v *viewInternal) clearRows() {
	v.collector.clearRows()
}

func (v *viewInternal) collectedRows() []*Row {
	return v.collector.collectedRows(v.view.TagKeys)
}

func (v *viewInternal) addSample(m *tag.Map, val float64) {
	if !v.isSubscribed() {
		return
	}
	sig := string(encodeWithKeys(m, v.view.TagKeys))
	v.collector.addSample(sig, val)
}

// A Data is a set of rows about usage of the single measure associated
// with the given view. Each row is specific to a unique set of tags.
type Data struct {
	View       *View
	Start, End time.Time
	Rows       []*Row
}

// Row is the collected value for a specific set of key value pairs a.k.a tags.
type Row struct {
	Tags []tag.Tag
	Data AggregationData
}

func (r *Row) String() string {
	var buffer bytes.Buffer
	buffer.WriteString("{ ")
	buffer.WriteString("{ ")
	for _, t := range r.Tags {
		buffer.WriteString(fmt.Sprintf("{%v %v}", t.Key.Name(), t.Value))
	}
	buffer.WriteString(" }")
	buffer.WriteString(fmt.Sprintf("%v", r.Data))
	buffer.WriteString(" }")
	return buffer.String()
}

// Equal returns true if both rows are equal. Tags are expected to be ordered
// by the key name. Even both rows have the same tags but the tags appear in
// different orders it will return false.
func (r *Row) Equal(other *Row) bool {
	if r == other {
		return true
	}
	return reflect.DeepEqual(r.Tags, other.Tags) && r.Data.equal(other.Data)
}

const maxNameLength = 255

// Returns true if the given string contains only printable characters.
func isPrintable(str string) bool {
	for _, r := range str {
		if !(r >= ' ' && r <= '~') {
			return false
		}
	}
	return true
}

func checkViewName(name string) error {
	if len(name) > maxNameLength {
		return fmt.Errorf("view name cannot be larger than %v", maxNameLength)
	}
	if !isPrintable(name) {
		return fmt.Errorf("view name needs to be an ASCII string")
	}
	return nil
}
