package tracing

import "fmt"

// Exporter is type of tracing target.
type Exporter string

const (
	StdoutExporter   Exporter = "stdout"
	OTLPgRPCExporter Exporter = "otlp_grpc"
	NoOpExporter     Exporter = "noop"
)

type Config struct {
	// Enabled is true, if tracing enabled.
	Enabled bool
	// Exporter is collector type.
	Exporter Exporter
	// Endpoint is collector endpoint for OTLP exporters.
	Endpoint string

	// Service is service name that will be used in tracing.
	// Mandatory.
	Service string
	// InstanceID is identity of service instance.
	// Optional.
	InstanceID string
	// Version is version of service instance.
	// Optional.
	Version string
}

func (c *Config) validate() error {
	if !c.Enabled {
		return nil
	}

	if c.Exporter != StdoutExporter && c.Exporter != OTLPgRPCExporter && c.Exporter != NoOpExporter {
		return fmt.Errorf("tracing config error: unknown exporter '%s', valid values are %v",
			c.Exporter, []string{string(StdoutExporter), string(OTLPgRPCExporter), string(NoOpExporter)})
	}

	if len(c.Service) == 0 {
		return fmt.Errorf("tracing config error: service name must be specified")
	}

	if c.Exporter == OTLPgRPCExporter && len(c.Endpoint) == 0 {
		return fmt.Errorf("tracing config error: exporter '%s' requires endpoint", c.Exporter)
	}

	return nil
}

func (c *Config) hasChange(other *Config) bool {
	if !c.Enabled && !other.Enabled {
		return false
	}
	if c.Enabled != other.Enabled {
		return true
	}

	if (c.Exporter == StdoutExporter && other.Exporter == StdoutExporter) ||
		(c.Exporter == NoOpExporter && other.Exporter == NoOpExporter) {
		return !c.serviceInfoEqual(other)
	}

	return c.Exporter != other.Exporter ||
		c.Endpoint != other.Endpoint ||
		!c.serviceInfoEqual(other)
}

func (c *Config) serviceInfoEqual(other *Config) bool {
	return c.Service == other.Service &&
		c.InstanceID == other.InstanceID &&
		c.Version == other.Version
}