// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// found in the LICENSE file.

package main

import (
	"context"
	"fmt"
	"math/rand"
	"net"
	"net/http"
	"os"
	"strconv"
	"testing"
	"time"

	devicePkg "go.fuchsia.dev/infra/devices"
)

const (
	successExitCode = 0
)

var (
	sigTermExitCode = rand.Int()%50 + 1
	failCode        = rand.Int()%50 + 51
)

func constructDummyCmd(fail bool) []string {
	failureExitCode := -1
	if fail {
		failureExitCode = failCode
	}
	return []string{
		"./dummy.sh",
		strconv.Itoa(failureExitCode),
		strconv.Itoa(sigTermExitCode),
	}
}

func checkExitCode(t *testing.T, actual int, expected int) {
	if actual != expected {
		t.Errorf("Expected exit code: %d Actual %d", expected, actual)
	}
}

// Test that runSubprocess propagates success code.
func TestSuccessfulSubprocess(t *testing.T) {
	cmd := constructDummyCmd(false)
	exitCode := runSubprocess(context.Background(), cmd)
	checkExitCode(t, exitCode, successExitCode)
}

// Test that runSubprocess propagates failure code.
func TestFailingSubprocess(t *testing.T) {
	cmd := constructDummyCmd(true)
	exitCode := runSubprocess(context.Background(), cmd)
	checkExitCode(t, exitCode, failCode)
}

// Test that sigterms are propagated to running subprocesses on context cancel.
func TestSigtermRunningSubprocess(t *testing.T) {
	cmd := constructDummyCmd(false)
	subprocessCtx, cancel := context.WithCancel(context.Background())
	go func() {
		time.Sleep(2 * time.Second)
		cancel()
	}()
	exitCode := runSubprocess(subprocessCtx, cmd)
	checkExitCode(t, exitCode, sigTermExitCode)
}

// Test that sigterms sent after the subprocess is done running do not get propagated.
func TestSigtermDoneSubprocess(t *testing.T) {
	cmd := constructDummyCmd(false)
	subprocessCtx, cancel := context.WithCancel(context.Background())
	go func() {
		time.Sleep(7 * time.Second)
		cancel()
	}()
	exitCode := runSubprocess(subprocessCtx, cmd)
	checkExitCode(t, exitCode, successExitCode)
}

func createMockDevice(name string, mac string, cmd []string) *devicePkg.DeviceTarget {
	target := &devicePkg.DeviceTarget{BootserverCmd: cmd}
	config := devicePkg.DeviceConfig{
		Network: devicePkg.NetworkProperties{
			Nodename: name,
			IPv4Addr: "000.000.00.0",
			Mac:      mac,
		},
	}
	target.SetConfig(config)
	return target
}

// Test running runBootservers with successful results using mock devices.
func TestBootserverSuccess(t *testing.T) {
	cmd := constructDummyCmd(false)
	devices := []*devicePkg.DeviceTarget{
		createMockDevice("dummy1", "00:00:00:00:00", cmd),
		createMockDevice("dummy2", "00:00:00:00:01", cmd),
	}
	exitCode := runBootservers(context.Background(), devices, []string{})
	checkExitCode(t, exitCode, successExitCode)
}

// Test running runBootservers with failed results using mock devices.
func TestBootserverFailure(t *testing.T) {
	devices := []*devicePkg.DeviceTarget{
		createMockDevice("dummy1", "00:00:00:00:00", constructDummyCmd(false)),
		createMockDevice("dummy2", "00:00:00:00:01", constructDummyCmd(true)),
	}
	exitCode := runBootservers(context.Background(), devices, []string{})
	checkExitCode(t, exitCode, failureExitCode)
}

// Test that NUC server does not start up when port environment variable isn't set.
func TestNUCServerNonexistence(t *testing.T) {
	var devices []*devicePkg.DeviceTarget
	srv, err := runNUCServer(context.Background(), devices, false)
	if srv != nil {
		t.Errorf("NUC server was created without port set.")
	} else if err != nil {
		t.Errorf("%v\n", err)
	}
}

// Test that NUC server is disabled when flag is set and port environment variable is set.
func TestNUCServerDisabled(t *testing.T) {
	var devices []*devicePkg.DeviceTarget
	os.Setenv(portEnvVar, "8000")
	srv, err := runNUCServer(context.Background(), devices, true)
	if srv != nil {
		t.Errorf("NUC server was created without port set.")
	} else if err != nil {
		t.Errorf("%v\n", err)
	}
	os.Setenv(portEnvVar, "")
}

// Test that NUC server is started up when port environment variable is set.
func TestNUCServerExistence(t *testing.T) {
	var devices []*devicePkg.DeviceTarget
	os.Setenv(portEnvVar, "8000")
	srv, err := runNUCServer(context.Background(), devices, false)
	os.Setenv(portEnvVar, "")
	if srv == nil {
		t.Errorf("NUC server was not created even with port var set.")
	}
	if err != nil {
		t.Errorf("%v\n", err)
	}
	srv.Shutdown(context.Background())
}

// Test that each device has an endpoint in the NUC server.
func TestNUCServerEndpoints(t *testing.T) {
	// Create mock devices
	cmd := constructDummyCmd(false)
	devices := []*devicePkg.DeviceTarget{
		createMockDevice("dummy1", "00:00:00:00:00", cmd),
		createMockDevice("dummy2", "00:00:00:00:01", cmd),
	}
	os.Setenv(portEnvVar, "8000")
	srv, err := runNUCServer(context.Background(), devices, false)
	os.Setenv(portEnvVar, "")
	if srv == nil {
		t.Errorf("NUC server was not created even with port var set.")
	}
	if err != nil {
		t.Errorf("%v\n", err)
	}

	// Wait until the webserver has come online.
	for {
		_, err := net.DialTimeout("tcp", "127.0.0.1:8000", 1*time.Second)
		if err == nil {
			break
		}
	}

	// Retrieve the chainloader from each endpoint.
	for _, device := range devices {
		resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:8000/%s.ipxe", device.Mac()))
		if err != nil {
			t.Errorf("%v\n", err)
		} else if resp.StatusCode != 200 {
			t.Errorf("Was unable to get chainloader for mac: %s", device.Mac())
		}
	}
	srv.Shutdown(context.Background())
}
