// 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/internal/measure/sampler"
	"v.io/x/sensorlog/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")
	}
}
