// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// package config provides methods for loading and querying a
// telemetry upload config file.
package config

import (
	"encoding/json"
	"os"
	"strings"

	"golang.org/x/telemetry/internal/telemetry"
)

// Config is a wrapper around telemetry.UploadConfig that provides some
// convenience methods for checking the contents of a report.
type Config struct {
	*telemetry.UploadConfig
	program         map[string]bool
	goos            map[string]bool
	goarch          map[string]bool
	goversion       map[string]bool
	pgversion       map[pgkey]bool
	pgcounter       map[pgkey]bool
	pgcounterprefix map[pgkey]bool
	pgstack         map[pgkey]bool
	rate            map[pgkey]float64
}

type pgkey struct {
	program, key string
}

func ReadConfig(file string) (*Config, error) {
	data, err := os.ReadFile(file)
	if err != nil {
		return nil, err
	}
	var cfg telemetry.UploadConfig
	if err := json.Unmarshal(data, &cfg); err != nil {
		return nil, err
	}
	return NewConfig(&cfg), nil
}

func NewConfig(cfg *telemetry.UploadConfig) *Config {
	ucfg := Config{UploadConfig: cfg}
	ucfg.goos = set(ucfg.GOOS)
	ucfg.goarch = set(ucfg.GOARCH)
	ucfg.goversion = set(ucfg.GoVersion)
	ucfg.program = make(map[string]bool, len(ucfg.Programs))
	ucfg.pgversion = make(map[pgkey]bool, len(ucfg.Programs))
	ucfg.pgcounter = make(map[pgkey]bool, len(ucfg.Programs))
	ucfg.pgcounterprefix = make(map[pgkey]bool, len(ucfg.Programs))
	ucfg.pgstack = make(map[pgkey]bool, len(ucfg.Programs))
	ucfg.rate = make(map[pgkey]float64)
	for _, p := range ucfg.Programs {
		ucfg.program[p.Name] = true
		for _, v := range p.Versions {
			ucfg.pgversion[pgkey{p.Name, v}] = true
		}
		for _, c := range p.Counters {
			for _, e := range Expand(c.Name) {
				ucfg.pgcounter[pgkey{p.Name, e}] = true
				ucfg.rate[pgkey{p.Name, e}] = c.Rate
			}
			prefix, _, found := strings.Cut(c.Name, ":")
			if found {
				ucfg.pgcounterprefix[pgkey{p.Name, prefix}] = true
			}
		}
		for _, s := range p.Stacks {
			ucfg.pgstack[pgkey{p.Name, s.Name}] = true
			ucfg.rate[pgkey{p.Name, s.Name}] = s.Rate
		}
	}
	return &ucfg
}

func (r *Config) HasProgram(s string) bool {
	return r.program[s]
}

func (r *Config) HasGOOS(s string) bool {
	return r.goos[s]
}

func (r *Config) HasGOARCH(s string) bool {
	return r.goarch[s]
}

func (r *Config) HasGoVersion(s string) bool {
	return r.goversion[s]
}

func (r *Config) HasVersion(program, version string) bool {
	return r.pgversion[pgkey{program, version}]
}

func (r *Config) HasCounter(program, counter string) bool {
	return r.pgcounter[pgkey{program, counter}]
}

func (r *Config) HasCounterPrefix(program, prefix string) bool {
	return r.pgcounterprefix[pgkey{program, prefix}]
}

func (r *Config) HasStack(program, stack string) bool {
	return r.pgstack[pgkey{program, stack}]
}

func (r *Config) Rate(program, name string) float64 {
	return r.rate[pgkey{program, name}]
}

func set(slice []string) map[string]bool {
	s := make(map[string]bool, len(slice))
	for _, v := range slice {
		s[v] = true
	}
	return s
}

// Expand takes a counter defined with buckets and expands it into distinct
// strings for each bucket
func Expand(counter string) []string {
	prefix, rest, hasBuckets := strings.Cut(counter, "{")
	var counters []string
	if hasBuckets {
		buckets := strings.Split(strings.TrimSuffix(rest, "}"), ",")
		for _, b := range buckets {
			counters = append(counters, prefix+b)
		}
	} else {
		counters = append(counters, prefix)
	}
	return counters
}
