/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 main

import (
	htrace "org/apache/htrace/client"
	"org/apache/htrace/common"
	"org/apache/htrace/conf"
	"reflect"
	"testing"
	"time"
)

func TestMetricsSinkStartupShutdown(t *testing.T) {
	cnfBld := conf.Builder{
		Values:   conf.TEST_VALUES(),
		Defaults: conf.DEFAULTS,
	}
	cnf, err := cnfBld.Build()
	if err != nil {
		t.Fatalf("failed to create conf: %s", err.Error())
	}
	msink := NewMetricsSink(cnf)
	msink.Shutdown()
}

func TestAddSpanMetrics(t *testing.T) {
	a := &ServerSpanMetrics{
		Written:       100,
		ServerDropped: 200,
	}
	b := &ServerSpanMetrics{
		Written:       500,
		ServerDropped: 100,
	}
	a.Add(b)
	if a.Written != 600 {
		t.Fatalf("SpanMetrics#Add failed to update #Written")
	}
	if a.ServerDropped != 300 {
		t.Fatalf("SpanMetrics#Add failed to update #Dropped")
	}
	if b.Written != 500 {
		t.Fatalf("SpanMetrics#Add updated b#Written")
	}
	if b.ServerDropped != 100 {
		t.Fatalf("SpanMetrics#Add updated b#Dropped")
	}
}

func compareTotals(a, b common.SpanMetricsMap) bool {
	for k, v := range a {
		if !reflect.DeepEqual(v, b[k]) {
			return false
		}
	}
	for k, v := range b {
		if !reflect.DeepEqual(v, a[k]) {
			return false
		}
	}
	return true
}

func waitForMetrics(msink *MetricsSink, expectedTotals common.SpanMetricsMap) {
	for {
		time.Sleep(1 * time.Millisecond)
		totals := msink.AccessServerTotals()
		if compareTotals(totals, expectedTotals) {
			return
		}
	}
}

func TestMetricsSinkMessages(t *testing.T) {
	cnfBld := conf.Builder{
		Values:   conf.TEST_VALUES(),
		Defaults: conf.DEFAULTS,
	}
	cnf, err := cnfBld.Build()
	if err != nil {
		t.Fatalf("failed to create conf: %s", err.Error())
	}
	msink := NewMetricsSink(cnf)
	totals := msink.AccessServerTotals()
	if len(totals) != 0 {
		t.Fatalf("Expected no data in the MetricsSink to start with.")
	}
	msink.UpdateMetrics(ServerSpanMetricsMap{
		"192.168.0.100": &ServerSpanMetrics{
			Written:       20,
			ServerDropped: 10,
		},
	})
	waitForMetrics(msink, common.SpanMetricsMap{
		"192.168.0.100": &common.SpanMetrics{
			Written:       20,
			ServerDropped: 10,
		},
	})
	msink.UpdateMetrics(ServerSpanMetricsMap{
		"192.168.0.100": &ServerSpanMetrics{
			Written:       200,
			ServerDropped: 100,
		},
	})
	msink.UpdateMetrics(ServerSpanMetricsMap{
		"192.168.0.100": &ServerSpanMetrics{
			Written:       1000,
			ServerDropped: 1000,
		},
	})
	waitForMetrics(msink, common.SpanMetricsMap{
		"192.168.0.100": &common.SpanMetrics{
			Written:       1220,
			ServerDropped: 1110,
		},
	})
	msink.UpdateMetrics(ServerSpanMetricsMap{
		"192.168.0.200": &ServerSpanMetrics{
			Written:       200,
			ServerDropped: 100,
		},
	})
	waitForMetrics(msink, common.SpanMetricsMap{
		"192.168.0.100": &common.SpanMetrics{
			Written:       1220,
			ServerDropped: 1110,
		},
		"192.168.0.200": &common.SpanMetrics{
			Written:       200,
			ServerDropped: 100,
		},
	})
	msink.Shutdown()
}

func TestMetricsSinkMessagesEviction(t *testing.T) {
	cnfBld := conf.Builder{
		Values:   conf.TEST_VALUES(),
		Defaults: conf.DEFAULTS,
	}
	cnfBld.Values[conf.HTRACE_METRICS_MAX_ADDR_ENTRIES] = "2"
	cnfBld.Values[conf.HTRACE_METRICS_HEARTBEAT_PERIOD_MS] = "1"
	cnf, err := cnfBld.Build()
	if err != nil {
		t.Fatalf("failed to create conf: %s", err.Error())
	}
	msink := NewMetricsSink(cnf)
	msink.UpdateMetrics(ServerSpanMetricsMap{
		"192.168.0.100": &ServerSpanMetrics{
			Written:       20,
			ServerDropped: 10,
		},
		"192.168.0.101": &ServerSpanMetrics{
			Written:       20,
			ServerDropped: 10,
		},
		"192.168.0.102": &ServerSpanMetrics{
			Written:       20,
			ServerDropped: 10,
		},
	})
	for {
		totals := msink.AccessServerTotals()
		if len(totals) == 2 {
			break
		}
	}
	msink.Shutdown()
}

func TestIngestedSpansMetricsRest(t *testing.T) {
	testIngestedSpansMetricsImpl(t, false)
}

func TestIngestedSpansMetricsPacked(t *testing.T) {
	testIngestedSpansMetricsImpl(t, true)
}

func testIngestedSpansMetricsImpl(t *testing.T, usePacked bool) {
	htraceBld := &MiniHTracedBuilder{Name: "TestIngestedSpansMetrics",
		DataDirs: make([]string, 2),
	}
	ht, err := htraceBld.Build()
	if err != nil {
		t.Fatalf("failed to create datastore: %s", err.Error())
	}
	defer ht.Close()
	var hcl *htrace.Client
	hcl, err = htrace.NewClient(ht.ClientConf(), &htrace.TestHooks {
		HrpcDisabled: !usePacked,
	})
	if err != nil {
		t.Fatalf("failed to create client: %s", err.Error())
	}

	NUM_TEST_SPANS := 12
	allSpans := createRandomTestSpans(NUM_TEST_SPANS)
	err = hcl.WriteSpans(&common.WriteSpansReq{
		Spans: allSpans,
	})
	if err != nil {
		t.Fatalf("WriteSpans failed: %s\n", err.Error())
	}
	for {
		var stats *common.ServerStats
		stats, err = hcl.GetServerStats()
		if err != nil {
			t.Fatalf("GetServerStats failed: %s\n", err.Error())
		}
		if stats.IngestedSpans == uint64(NUM_TEST_SPANS) {
			break
		}
		time.Sleep(1 * time.Millisecond)
	}
}

func TestCircBuf32(t *testing.T) {
	cbuf := NewCircBufU32(3)
	// We arbitrarily define that empty circular buffers have an average of 0.
	if cbuf.Average() != 0 {
		t.Fatalf("expected empty CircBufU32 to have an average of 0.\n")
	}
	if cbuf.Max() != 0 {
		t.Fatalf("expected empty CircBufU32 to have a max of 0.\n")
	}
	cbuf.Append(2)
	if cbuf.Average() != 2 {
		t.Fatalf("expected one-element CircBufU32 to have an average of 2.\n")
	}
	cbuf.Append(10)
	if cbuf.Average() != 6 {
		t.Fatalf("expected two-element CircBufU32 to have an average of 6.\n")
	}
	cbuf.Append(12)
	if cbuf.Average() != 8 {
		t.Fatalf("expected three-element CircBufU32 to have an average of 8.\n")
	}
	cbuf.Append(14)
	// The 14 overwrites the original 2 element.
	if cbuf.Average() != 12 {
		t.Fatalf("expected three-element CircBufU32 to have an average of 12.\n")
	}
	cbuf.Append(1)
	// The 1 overwrites the original 10 element.
	if cbuf.Average() != 9 {
		t.Fatalf("expected three-element CircBufU32 to have an average of 12.\n")
	}
	if cbuf.Max() != 14 {
		t.Fatalf("expected three-element CircBufU32 to have a max of 14.\n")
	}
}
