// Copyright 2019 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 ocagent_test

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"sync"
	"testing"
	"time"

	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/event/core"
	"golang.org/x/tools/internal/event/export"
	"golang.org/x/tools/internal/event/export/metric"
	"golang.org/x/tools/internal/event/export/ocagent"
	"golang.org/x/tools/internal/event/keys"
	"golang.org/x/tools/internal/event/label"
)

const testNodeStr = `{
	"node":{
		"identifier":{
			"host_name":"tester",
			"pid":1,
			"start_timestamp":"1970-01-01T00:00:00Z"
		},
		"library_info":{
			"language":4,
			"exporter_version":"0.0.1",
			"core_library_version":"x/tools"
		},
		"service_info":{
			"name":"ocagent-tests"
		}
	},`

var (
	keyDB     = keys.NewString("db", "the database name")
	keyMethod = keys.NewString("method", "a metric grouping key")
	keyRoute  = keys.NewString("route", "another metric grouping key")

	key1DB = keys.NewString("1_db", "A test string key")

	key2aAge      = keys.NewFloat64("2a_age", "A test float64 key")
	key2bTTL      = keys.NewFloat32("2b_ttl", "A test float32 key")
	key2cExpiryMS = keys.NewFloat64("2c_expiry_ms", "A test float64 key")

	key3aRetry = keys.NewBoolean("3a_retry", "A test boolean key")
	key3bStale = keys.NewBoolean("3b_stale", "Another test boolean key")

	key4aMax      = keys.NewInt("4a_max", "A test int key")
	key4bOpcode   = keys.NewInt8("4b_opcode", "A test int8 key")
	key4cBase     = keys.NewInt16("4c_base", "A test int16 key")
	key4eChecksum = keys.NewInt32("4e_checksum", "A test int32 key")
	key4fMode     = keys.NewInt64("4f_mode", "A test int64 key")

	key5aMin     = keys.NewUInt("5a_min", "A test uint key")
	key5bMix     = keys.NewUInt8("5b_mix", "A test uint8 key")
	key5cPort    = keys.NewUInt16("5c_port", "A test uint16 key")
	key5dMinHops = keys.NewUInt32("5d_min_hops", "A test uint32 key")
	key5eMaxHops = keys.NewUInt64("5e_max_hops", "A test uint64 key")

	recursiveCalls = keys.NewInt64("recursive_calls", "Number of recursive calls")
	bytesIn        = keys.NewInt64("bytes_in", "Number of bytes in")           //, unit.Bytes)
	latencyMs      = keys.NewFloat64("latency", "The latency in milliseconds") //, unit.Milliseconds)

	metricLatency = metric.HistogramFloat64{
		Name:        "latency_ms",
		Description: "The latency of calls in milliseconds",
		Keys:        []label.Key{keyMethod, keyRoute},
		Buckets:     []float64{0, 5, 10, 25, 50},
	}

	metricBytesIn = metric.HistogramInt64{
		Name:        "latency_ms",
		Description: "The latency of calls in milliseconds",
		Keys:        []label.Key{keyMethod, keyRoute},
		Buckets:     []int64{0, 10, 50, 100, 500, 1000, 2000},
	}

	metricRecursiveCalls = metric.Scalar{
		Name:        "latency_ms",
		Description: "The latency of calls in milliseconds",
		Keys:        []label.Key{keyMethod, keyRoute},
	}
)

type testExporter struct {
	ocagent *ocagent.Exporter
	sent    fakeSender
}

func registerExporter() *testExporter {
	exporter := &testExporter{}
	cfg := ocagent.Config{
		Host:    "tester",
		Process: 1,
		Service: "ocagent-tests",
		Client:  &http.Client{Transport: &exporter.sent},
	}
	cfg.Start, _ = time.Parse(time.RFC3339Nano, "1970-01-01T00:00:00Z")
	exporter.ocagent = ocagent.Connect(&cfg)

	metrics := metric.Config{}
	metricLatency.Record(&metrics, latencyMs)
	metricBytesIn.Record(&metrics, bytesIn)
	metricRecursiveCalls.SumInt64(&metrics, recursiveCalls)

	e := exporter.ocagent.ProcessEvent
	e = metrics.Exporter(e)
	e = spanFixer(e)
	e = export.Spans(e)
	e = export.Labels(e)
	e = timeFixer(e)
	event.SetExporter(e)
	return exporter
}

func timeFixer(output event.Exporter) event.Exporter {
	start, _ := time.Parse(time.RFC3339Nano, "1970-01-01T00:00:30Z")
	at, _ := time.Parse(time.RFC3339Nano, "1970-01-01T00:00:40Z")
	end, _ := time.Parse(time.RFC3339Nano, "1970-01-01T00:00:50Z")
	return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
		switch {
		case event.IsStart(ev):
			ev = core.CloneEvent(ev, start)
		case event.IsEnd(ev):
			ev = core.CloneEvent(ev, end)
		default:
			ev = core.CloneEvent(ev, at)
		}
		return output(ctx, ev, lm)
	}
}

func spanFixer(output event.Exporter) event.Exporter {
	return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
		if event.IsStart(ev) {
			span := export.GetSpan(ctx)
			span.ID = export.SpanContext{}
		}
		return output(ctx, ev, lm)
	}
}

func (e *testExporter) Output(route string) []byte {
	e.ocagent.Flush()
	return e.sent.get(route)
}

func checkJSON(t *testing.T, got, want []byte) {
	// compare the compact form, to allow for formatting differences
	g := &bytes.Buffer{}
	if err := json.Compact(g, got); err != nil {
		t.Fatal(err)
	}
	w := &bytes.Buffer{}
	if err := json.Compact(w, want); err != nil {
		t.Fatal(err)
	}
	if g.String() != w.String() {
		t.Fatalf("Got:\n%s\nWant:\n%s", g, w)
	}
}

type fakeSender struct {
	mu   sync.Mutex
	data map[string][]byte
}

func (s *fakeSender) get(route string) []byte {
	s.mu.Lock()
	defer s.mu.Unlock()
	data, found := s.data[route]
	if found {
		delete(s.data, route)
	}
	return data
}

func (s *fakeSender) RoundTrip(req *http.Request) (*http.Response, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.data == nil {
		s.data = make(map[string][]byte)
	}
	data, err := io.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}
	path := req.URL.EscapedPath()
	if _, found := s.data[path]; found {
		return nil, fmt.Errorf("duplicate delivery to %v", path)
	}
	s.data[path] = data
	return &http.Response{
		Status:     "200 OK",
		StatusCode: 200,
		Proto:      "HTTP/1.0",
		ProtoMajor: 1,
		ProtoMinor: 0,
	}, nil
}
