// 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 sampler_test

import (
	"strings"
	"testing"
	"time"

	"v.io/v23/context"
	tu "v.io/x/ref/test/testutil"
	"v.io/x/sensorlog_lite/internal/measure/sampler"
	"v.io/x/sensorlog_lite/internal/sbmodel"
)

// Runs the sampler script and verifies that the callback was called with the
// expected value or error.
func runSamplerTest(t *testing.T, samDef *sbmodel.SamplerDef) sbmodel.VDataPoint {
	ctx, cancel := context.RootContext()
	defer cancel()

	var gotRes *sampler.MeasureResult
	start := time.Now()
	if err := sampler.Run(ctx, samDef, func(res *sampler.MeasureResult) error {
		gotRes = res
		return nil
	}); err != nil {
		t.Fatal(tu.FormatLogLine(3, "unexpected sampling error: %v", err))
	}
	end := time.Now()

	if gotRes == nil {
		t.Fatal(tu.FormatLogLine(3, "sampler callback was not called"))
	}

	if gotRes.Time.Before(start) || gotRes.Time.After(end) {
		t.Error(tu.FormatLogLine(3, "invalid time: %v, expected between %v and %v", gotRes.Time, start, end))
	}

	return gotRes.Data
}

func runSamplerTestForValue(t *testing.T, samDef *sbmodel.SamplerDef, expectVal float64) {
	res := runSamplerTest(t, samDef)
	switch res := res.(type) {
	case sbmodel.VDataPointValue:
		if res.Value != expectVal {
			t.Error(tu.FormatLogLine(2, "unexpected value, got: %v, want: %v", res.Value, expectVal))
		}
	default:
		t.Error(tu.FormatLogLine(2, "unexpected type, got: %v, want value: %v", res, expectVal))
	}
}

func runSamplerTestForError(t *testing.T, samDef *sbmodel.SamplerDef, expectErrPrefix string) {
	res := runSamplerTest(t, samDef)
	switch res := res.(type) {
	case sbmodel.VDataPointError:
		if !strings.HasPrefix(res.Value, expectErrPrefix) {
			t.Error(tu.FormatLogLine(2, "unexpected error, got: %v, want prefix: %v", res.Value, expectErrPrefix))
		}
	default:
		t.Error(tu.FormatLogLine(2, "unexpected type, got: %v, want error with prefix: %v", res, expectErrPrefix))
	}
}

func TestSamplerRun(t *testing.T) {
	runSamplerTestForValue(t, &sbmodel.SamplerDef{
		Script:   `echo 42`,
		Start:    time.Now(),
		Interval: time.Second, // 7.5M years overflows time.Duration
	}, 42.0)

	runSamplerTestForValue(t, &sbmodel.SamplerDef{
		Script: `
for i in $(seq 10000); do :; done
printf "%f\n" -12.73
exit 0
`,
		Start:    time.Now(),
		Interval: time.Millisecond,
	}, -12.73)

	runSamplerTestForError(t, &sbmodel.SamplerDef{
		Script:   `echo 42; exit 1`,
		Start:    time.Now(),
		Interval: time.Second,
	}, "Script error")

	runSamplerTestForError(t, &sbmodel.SamplerDef{
		Script:   `exit 0`,
		Start:    time.Now(),
		Interval: time.Second,
	}, "Parse error")

	runSamplerTestForError(t, &sbmodel.SamplerDef{
		Script:   `echo 42foo`,
		Start:    time.Now(),
		Interval: time.Second,
	}, "Parse error")

	runSamplerTestForError(t, &sbmodel.SamplerDef{
		Script:   `echo 42; echo 47`,
		Start:    time.Now(),
		Interval: time.Second,
	}, "Parse error")
}

func TestSamplerCancel(t *testing.T) {
	ctx, cancel := context.RootContext()
	defer cancel()

	// The script sleeps for 10 seconds, not interruptible by SIGINT/SIGTERM.
	samDef := &sbmodel.SamplerDef{
		Script: `
trap 'sleep 10' INT TERM
sleep 10
echo 42
`,
		Start:    time.Now(),
		Interval: time.Second,
	}
	// Asynchronously run sampler, cancelling shortly after.
	done := make(chan error, 1)
	go func() {
		done <- sampler.Run(ctx, samDef, func(res *sampler.MeasureResult) error {
			t.Errorf("worker was cancelled, result callback should not have been called, got: %v", res.Data)
			return nil
		})
	}()

	time.Sleep(100 * time.Millisecond)
	cancelTime := time.Now()
	cancel()

	if err := <-done; err != nil {
		t.Errorf("unexpected sampling error: %v", err)
	}
	// Cancel should have killed the script using SIGKILL a short time after the
	// script failed to exit on SIGINT.
	if cancelTime.Add(1 * time.Second).Before(time.Now()) {
		t.Errorf("sampling script took more than a second to stop")
	}
}
