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

// Same requirements as internal/coordinator/pool/reverse.go.
//go:build linux || darwin
// +build linux darwin

package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"testing"
	"time"

	"golang.org/x/build"
	"golang.org/x/build/internal/coordinator/pool"
	"golang.org/x/build/revdial/v2"
)

// coordinatorServer creates a server and listener for the coordinator side of
// revdial. They should be closed when done.
func coordinatorServer() (*http.Server, net.Listener, error) {
	mux := http.NewServeMux()
	mux.HandleFunc("/reverse", pool.HandleReverse)
	mux.Handle("/revdial", revdial.ConnHandler())

	ln, err := net.Listen("tcp", "")
	if err != nil {
		return nil, nil, fmt.Errorf(`net.Listen(":"): %v`, err)
	}

	cert, err := tls.X509KeyPair([]byte(build.DevCoordinatorCA), []byte(build.DevCoordinatorKey))
	if err != nil {
		return nil, nil, fmt.Errorf("error creating TLS cert: %v", err)
	}

	ln = tls.NewListener(ln, &tls.Config{
		Certificates: []tls.Certificate{cert},
	})

	addr := ln.Addr().String()
	srv := &http.Server{
		Addr:    addr,
		Handler: mux,
	}
	return srv, ln, nil
}

// testReverseDial verifies that a revdial connection can be established and
// registered in the coordinator reverse pool at coordAddr.
func testReverseDial(t *testing.T, coordAddr, hostType string) {
	t.Helper()

	oldCoordinator := *coordinator
	defer func() {
		*coordinator = oldCoordinator
	}()
	*coordinator = coordAddr

	// N.B. We don't need to set *hostname to anything in particular as it
	// is only advisory in the coordinator. It is not used to connect back
	// to reverse buildlets.

	oldReverseType := *reverseType
	defer func() {
		*reverseType = oldReverseType
	}()
	*reverseType = hostType

	ln, err := dialCoordinator()
	if err != nil {
		t.Fatalf("dialCoordinator got err %v want nil", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/status", handleStatus)
	srv := &http.Server{
		Handler: mux,
	}
	c := make(chan error, 1)
	go func() {
		c <- srv.Serve(ln)
	}()
	defer func() {
		srv.Close()
		err := <-c
		if err != http.ErrServerClosed {
			t.Errorf("Server shutdown got err %v want ErrServerClosed", err)
		}
	}()

	// Verify that we eventually get the "buildlet" registered with the pool.
	tick := time.NewTicker(10 * time.Millisecond)
	defer tick.Stop()
	start := time.Now()
	for range tick.C {
		if time.Since(start) > 1*time.Second {
			t.Fatalf("Buildlet failed to register within 1s.")
		}

		types := pool.ReversePool().HostTypes()
		for _, typ := range types {
			if typ == hostType {
				// Success!
				return
			}
		}
	}
}

// TestReverseDial verifies that a revdial connection can be established and
// registered in the coordinator reverse pool.
func TestReverseDial(t *testing.T) {
	pool.SetBuilderMasterKey([]byte(devMasterKey))

	srv, ln, err := coordinatorServer()
	if err != nil {
		t.Fatalf("serveCoordinator got err %v want nil", err)
	}
	go srv.Serve(ln)
	defer srv.Close()

	const hostType = "test-reverse-dial"
	testReverseDial(t, srv.Addr, hostType)
}

// TestReverseDialRedirect verifies that a revdial connection works with a 307
// redirect to the endpoints. The coordinator will do this in dev mode.
func TestReverseDialRedirect(t *testing.T) {
	pool.SetBuilderMasterKey([]byte(devMasterKey))

	srv, ln, err := coordinatorServer()
	if err != nil {
		t.Fatalf("serveCoordinator got err %v want nil", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/redirected/reverse", pool.HandleReverse)
	mux.Handle("/redirected/revdial", revdial.ConnHandler())

	redirect := func(w http.ResponseWriter, r *http.Request) {
		u := *r.URL
		u.Path = "/redirected/" + u.Path
		http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect)
	}
	mux.HandleFunc("/reverse", redirect)
	mux.HandleFunc("/revdial", redirect)
	srv.Handler = mux

	go srv.Serve(ln)
	defer srv.Close()

	const hostType = "test-reverse-dial-redirect"
	testReverseDial(t, srv.Addr, hostType)
}
