// Copyright 2015 The Vanadium 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 debuglib

import (
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/services/logreader"
	"v.io/v23/services/stats"
	s_vtrace "v.io/v23/services/vtrace"
	"v.io/v23/vdl"
	"v.io/v23/verror"
	"v.io/v23/vtrace"
	"v.io/x/lib/vlog"
	libstats "v.io/x/ref/lib/stats"
	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
)

func TestDebugServer(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	tracedContext := func(ctx *context.T) *context.T {
		ctx, _ = vtrace.WithNewTrace(ctx)
		vtrace.ForceCollect(ctx, 0)
		return ctx
	}
	rootName = "debug"

	workdir, err := ioutil.TempDir("", "logreadertest")
	if err != nil {
		t.Fatalf("ioutil.TempDir: %v", err)
	}
	defer os.RemoveAll(workdir)
	if err = ioutil.WriteFile(filepath.Join(workdir, "test.INFO"), []byte("test"), os.FileMode(0644)); err != nil {
		t.Fatalf("ioutil.WriteFile failed: %v", err)
	}

	// Use logger configured with the directory that we want to use for this test.
	testLogger := vlog.NewLogger("TestDebugServer")
	testLogger.Configure(vlog.LogDir(workdir))
	ctx = context.WithLogger(ctx, testLogger)

	disp := NewDispatcher(nil)
	ctx, server, err := v23.WithNewDispatchingServer(ctx, "", disp)
	if err != nil {
		t.Fatalf("failed to start debug server: %v", err)
	}
	endpoint := server.Status().Endpoints[0].String()

	// Access a logs directory that exists.
	{
		results, _, err := testutil.GlobName(ctx, naming.JoinAddressName(endpoint, "debug/logs"), "*")
		if err != nil {
			t.Errorf("Glob failed: %v", err)
		}
		check(t, []string{"test.INFO"}, results)
	}

	// Access a logs directory that doesn't exist.
	{
		results, _, err := testutil.GlobName(ctx, naming.JoinAddressName(endpoint, "debug/logs/nowheretobefound"), "*")
		if len(results) != 0 {
			t.Errorf("unexpected result. Got %v, want ''", results)
		}
		if err != nil {
			t.Errorf("unexpected error value: %v", err)
		}
	}

	// Access a log file that exists.
	{
		lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "debug/logs/test.INFO"))
		size, err := lf.Size(tracedContext(ctx))
		if err != nil {
			t.Errorf("Size failed: %v", err)
		}
		if expected := int64(len("test")); size != expected {
			t.Errorf("unexpected result. Got %v, want %v", size, expected)
		}
	}

	// Access a log file that doesn't exist.
	{
		lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "debug/logs/nosuchfile.INFO"))
		_, err = lf.Size(tracedContext(ctx))
		if expected := verror.ErrNoExist.ID; verror.ErrorID(err) != expected {
			t.Errorf("unexpected error value, got %v, want: %v", err, expected)
		}
	}

	// Access a stats object that exists.
	{
		foo := libstats.NewInteger("testing/foo")
		foo.Set(123)

		st := stats.StatsClient(naming.JoinAddressName(endpoint, "debug/stats/testing/foo"))
		v, err := st.Value(tracedContext(ctx))
		if err != nil {
			t.Errorf("Value failed: %v", err)
		}
		vv := vdl.ValueOf(v)
		if want := vdl.IntValue(vdl.Int64Type, 123); !vdl.EqualValue(vv, want) {
			t.Errorf("unexpected result. got %v, want %v", vv, want)
		}
	}

	// Access a stats object that doesn't exists.
	{
		st := stats.StatsClient(naming.JoinAddressName(endpoint, "debug/stats/testing/nobodyhome"))
		_, err = st.Value(tracedContext(ctx))
		if expected := verror.ErrNoExist.ID; verror.ErrorID(err) != expected {
			t.Errorf("unexpected error value, got %v, want: %v", err, expected)
		}
	}

	// Access vtrace.
	{
		vt := s_vtrace.StoreClient(naming.JoinAddressName(endpoint, "debug/vtrace"))
		call, err := vt.AllTraces(ctx)
		if err != nil {
			t.Errorf("AllTraces failed: %v", err)
		}
		ntraces := 0
		stream := call.RecvStream()
		for stream.Advance() {
			stream.Value()
			ntraces++
		}
		if err = stream.Err(); err != nil && err != io.EOF {
			t.Fatalf("Unexpected error reading trace stream: %s", err)
		}
		if ntraces != 4 {
			t.Errorf("We expected 4 traces, got: %d", ntraces)
		}
	}

	// Glob from the root.
	{
		ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
		defer cancel()

		ns := v23.GetNamespace(ctx)
		ns.SetRoots(naming.JoinAddressName(endpoint, "debug"))

		c, err := ns.Glob(ctx, "logs/...")
		if err != nil {
			t.Errorf("ns.Glob failed: %v", err)
		}
		results := []string{}
		for res := range c {
			switch v := res.(type) {
			case *naming.GlobReplyEntry:
				results = append(results, v.Value.Name)
			}
		}
		expected := []string{
			"logs",
			"logs/test.INFO",
		}
		check(t, expected, results)

		c, err = ns.Glob(ctx, "stats/testing/*")
		if err != nil {
			t.Errorf("ns.Glob failed: %v", err)
		}
		results = []string{}
		for res := range c {
			t.Logf("got %v", res)
			switch v := res.(type) {
			case *naming.GlobReplyEntry:
				results = append(results, v.Value.Name)
			}
		}
		sort.Strings(results)
		expected = []string{
			"stats/testing/foo",
		}
		if !reflect.DeepEqual(expected, results) {
			t.Errorf("unexpected result. Got %v, want %v", results, expected)
		}

		c, err = ns.Glob(ctx, "*")
		if err != nil {
			t.Errorf("ns.Glob failed: %v", err)
		}
		results = []string{}
		for res := range c {
			switch v := res.(type) {
			case *naming.GlobReplyEntry:
				results = append(results, v.Value.Name)
			}
		}
		sort.Strings(results)
		expected = []string{
			"http",
			"logs",
			"pprof",
			"stats",
			"vtrace",
		}
		if !reflect.DeepEqual(expected, results) {
			t.Errorf("unexpected result. Got %v, want %v", results, expected)
		}

		c, err = ns.Glob(ctx, "...")
		if err != nil {
			t.Errorf("ns.Glob failed: %v", err)
		}
		results = []string{}
		for res := range c {
			switch v := res.(type) {
			case *naming.GlobReplyEntry:
				if strings.HasPrefix(v.Value.Name, "stats/") && !strings.HasPrefix(v.Value.Name, "stats/testing/") {
					// Skip any non-testing stats.
					continue
				}
				results = append(results, v.Value.Name)
			}
		}
		expected = []string{
			"",
			"logs",
			"logs/test.INFO",
			"pprof",
			"stats",
			"stats/testing/foo",
			"vtrace",
		}
		check(t, expected, results)
	}
}

func check(t *testing.T, expected, results []string) {
	resultSet := map[string]bool{}
	for _, result := range results {
		resultSet[result] = true
	}
	var missing []string
	for _, expected := range expected {
		if !resultSet[expected] {
			missing = append(missing, expected)
		}
	}
	if len(missing) > 0 {
		t.Errorf("Result %v missing expected results %v", results, missing)
	}
}
