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

//go:build linux || darwin
// +build linux darwin

package schedule

import (
	"context"
	"fmt"
	"runtime"
	"testing"
	"time"

	"golang.org/x/build/buildlet"
	"golang.org/x/build/dashboard"
	cpool "golang.org/x/build/internal/coordinator/pool"
	"golang.org/x/build/internal/coordinator/pool/queue"
	"golang.org/x/build/internal/spanlog"
)

type discardLogger struct{}

func (discardLogger) LogEventTime(event string, optText ...string) {}

func (discardLogger) CreateSpan(event string, optText ...string) spanlog.Span {
	return CreateSpan(discardLogger{}, event, optText...)
}

// step is a test step for TestScheduler
type step func(*testing.T, *Scheduler)

// getBuildletCall represents a call to GetBuildlet.
type getBuildletCall struct {
	si        *queue.SchedItem
	ctx       context.Context
	ctxCancel context.CancelFunc

	done      chan struct{} // closed when call done
	gotClient buildlet.Client
	gotErr    error
}

func newGetBuildletCall(si *queue.SchedItem) *getBuildletCall {
	c := &getBuildletCall{
		si:   si,
		done: make(chan struct{}),
	}
	c.ctx, c.ctxCancel = context.WithCancel(context.Background())
	return c
}

func (c *getBuildletCall) cancel(t *testing.T, s *Scheduler) { c.ctxCancel() }

// start is a step (assignable to type step) that starts a
// s.GetBuildlet call and waits for it to either succeed or get
// blocked in the scheduler.
func (c *getBuildletCall) start(t *testing.T, s *Scheduler) {
	t.Logf("starting buildlet call for SchedItem=%p", c.si)
	go func() {
		c.gotClient, c.gotErr = s.GetBuildlet(c.ctx, c.si)
		close(c.done)
	}()

	// Wait for si to be enqueued, or this call to be satisified.
	if !trueSoon(func() bool {
		select {
		case <-c.done:
			return true
		default:
			return s.hasWaiter(c.si)
		}
	}) {
		t.Fatalf("timeout waiting for GetBuildlet call to run to its blocking point")
	}
}

func trueSoon(f func() bool) bool {
	deadline := time.Now().Add(5 * time.Second)
	for {
		if time.Now().After(deadline) {
			return false
		}
		if f() {
			return true
		}
		time.Sleep(5 * time.Millisecond)
	}
}

// wantGetBuildlet is a step (assignable to type step) that) that expects
// the GetBuildlet call to succeed.
func (c *getBuildletCall) wantGetBuildlet(t *testing.T, s *Scheduler) {
	timer := time.NewTimer(5 * time.Second)
	defer timer.Stop()
	t.Logf("waiting on sched.getBuildlet(%q) ...", c.si.HostType)
	select {
	case <-c.done:
		t.Logf("got sched.getBuildlet(%q).", c.si.HostType)
		if c.gotErr != nil {
			t.Fatalf("GetBuildlet(%q): %v", c.si.HostType, c.gotErr)
		}
	case <-timer.C:
		stack := make([]byte, 1<<20)
		stack = stack[:runtime.Stack(stack, true)]
		t.Fatalf("timeout waiting for buildlet of type %q; stacks:\n%s", c.si.HostType, stack)
	}
}

type fakePool struct {
	poolChan map[string]chan interface{} // hostType -> { buildlet.Client | error}
}

func (f *fakePool) GetBuildlet(ctx context.Context, hostType string, lg cpool.Logger, item *queue.SchedItem) (buildlet.Client, error) {
	c, ok := f.poolChan[hostType]
	if !ok {
		return nil, fmt.Errorf("pool doesn't support host type %q", hostType)
	}
	select {
	case v := <-c:
		if c, ok := v.(buildlet.Client); ok {
			return c, nil
		}
		return nil, v.(error)
	case <-ctx.Done():
		return nil, ctx.Err()
	}
}

func (fakePool) String() string { return "testing poolChan" }

func TestScheduler(t *testing.T) {
	defer func() { cpool.TestPoolHook = nil }()

	var pool *fakePool // initialized per test below
	// buildletAvailable is a step that creates a buildlet to the pool.
	buildletAvailable := func(hostType string) step {
		return func(t *testing.T, s *Scheduler) {
			bc := buildlet.NewClient("127.0.0.1:9999", buildlet.NoKeyPair) // dummy
			t.Logf("adding buildlet to pool for %q...", hostType)
			ch := pool.poolChan[hostType]
			ch <- bc
			t.Logf("added buildlet to pool for %q (ch=%p)", hostType, ch)
		}
	}

	tests := []struct {
		name  string
		steps func() []step
	}{
		{
			name: "simple-get-before-available",
			steps: func() []step {
				si := &queue.SchedItem{HostType: "test-host-foo"}
				fooGet := newGetBuildletCall(si)
				return []step{
					fooGet.start,
					buildletAvailable("test-host-foo"),
					fooGet.wantGetBuildlet,
				}
			},
		},
		{
			name: "simple-get-already-available",
			steps: func() []step {
				si := &queue.SchedItem{HostType: "test-host-foo"}
				fooGet := newGetBuildletCall(si)
				return []step{
					buildletAvailable("test-host-foo"),
					fooGet.start,
					fooGet.wantGetBuildlet,
				}
			},
		},
		{
			name: "cancel-context-removes-waiter",
			steps: func() []step {
				si := &queue.SchedItem{HostType: "test-host-foo"}
				get := newGetBuildletCall(si)
				return []step{
					get.start,
					get.cancel,
					func(t *testing.T, s *Scheduler) {
						if !trueSoon(func() bool { return !s.hasWaiter(si) }) {
							t.Errorf("still have SchedItem in waiting set")
						}
					},
				}
			},
		},
	}
	for _, tt := range tests {
		pool = &fakePool{poolChan: map[string]chan interface{}{}}
		pool.poolChan["test-host-foo"] = make(chan interface{}, 1)
		pool.poolChan["test-host-bar"] = make(chan interface{}, 1)

		cpool.TestPoolHook = func(*dashboard.HostConfig) cpool.Buildlet { return pool }
		t.Run(tt.name, func(t *testing.T) {
			s := NewScheduler()
			for i, st := range tt.steps() {
				t.Logf("step %v...", i)
				st(t, s)
			}
		})
	}
}
