// 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/ioutil"
	"net/http"
	"sync"
	"testing"
	"time"

	"golang.org/x/tools/internal/telemetry/event"
	"golang.org/x/tools/internal/telemetry/export"
	"golang.org/x/tools/internal/telemetry/export/metric"
	"golang.org/x/tools/internal/telemetry/export/ocagent"
)

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     = event.NewStringKey("db", "the database name")
	keyMethod = event.NewStringKey("method", "a metric grouping key")
	keyRoute  = event.NewStringKey("route", "another metric grouping key")

	key1DB = event.NewStringKey("1_db", "A test string key")

	key2aAge      = event.NewFloat64Key("2a_age", "A test float64 key")
	key2bTTL      = event.NewFloat32Key("2b_ttl", "A test float32 key")
	key2cExpiryMS = event.NewFloat64Key("2c_expiry_ms", "A test float64 key")

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

	key4aMax      = event.NewIntKey("4a_max", "A test int key")
	key4bOpcode   = event.NewInt8Key("4b_opcode", "A test int8 key")
	key4cBase     = event.NewInt16Key("4c_base", "A test int16 key")
	key4eChecksum = event.NewInt32Key("4e_checksum", "A test int32 key")
	key4fMode     = event.NewInt64Key("4f_mode", "A test int64 key")

	key5aMin     = event.NewUIntKey("5a_min", "A test uint key")
	key5bMix     = event.NewUInt8Key("5b_mix", "A test uint8 key")
	key5cPort    = event.NewUInt16Key("5c_port", "A test uint16 key")
	key5dMinHops = event.NewUInt32Key("5d_min_hops", "A test uint32 key")
	key5eMaxHops = event.NewUInt64Key("5e_max_hops", "A test uint64 key")

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

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

	metricBytesIn = metric.HistogramInt64{
		Name:        "latency_ms",
		Description: "The latency of calls in milliseconds",
		Keys:        []event.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:        []event.Key{keyMethod, keyRoute},
	}
)

type testExporter struct {
	metrics metric.Exporter
	ocagent *ocagent.Exporter
	sent    fakeSender
	start   time.Time
	at      time.Time
	end     time.Time
}

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)
	exporter.start, _ = time.Parse(time.RFC3339Nano, "1970-01-01T00:00:30Z")
	exporter.at, _ = time.Parse(time.RFC3339Nano, "1970-01-01T00:00:40Z")
	exporter.end, _ = time.Parse(time.RFC3339Nano, "1970-01-01T00:00:50Z")

	metricLatency.Record(&exporter.metrics, latencyMs)
	metricBytesIn.Record(&exporter.metrics, bytesIn)
	metricRecursiveCalls.SumInt64(&exporter.metrics, recursiveCalls)

	event.SetExporter(exporter)
	return exporter
}

func (e *testExporter) ProcessEvent(ctx context.Context, ev event.Event) (context.Context, event.Event) {
	switch {
	case ev.IsStartSpan():
		ev.At = e.start
	case ev.IsEndSpan():
		ev.At = e.end
	default:
		ev.At = e.at
	}
	ctx, ev = export.Tag(ctx, ev)
	ctx, ev = export.ContextSpan(ctx, ev)
	ctx, ev = e.metrics.ProcessEvent(ctx, ev)
	ctx, ev = e.ocagent.ProcessEvent(ctx, ev)
	if ev.IsStartSpan() {
		span := export.GetSpan(ctx)
		span.ID = export.SpanContext{}
	}
	return ctx, ev
}

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 := ioutil.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
}
