// Copyright 2019 The Fuchsia 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 subprocess

import (
	"bytes"
	"context"
	"errors"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"go.fuchsia.dev/fuchsia/tools/lib/clock"
)

func TestRun(t *testing.T) {
	t.Run("Run", func(t *testing.T) {
		t.Run("should execute a command", func(t *testing.T) {
			r := Runner{
				Env: []string{"FOO=bar"}, // Cover env var handling.
			}
			message := "Hello, World!"
			command := []string{"echo", message}

			stdout := new(bytes.Buffer)
			stderr := new(bytes.Buffer)
			if err := r.Run(context.Background(), command, stdout, stderr); err != nil {
				t.Fatal(err)
			}

			stdoutS := strings.TrimSpace(stdout.String())
			if stdoutS != message {
				t.Fatalf("Expected output %q, but got %q", message, stdoutS)
			}

			stderrS := strings.TrimSpace(stderr.String())
			if stderrS != "" {
				t.Fatalf("Expected empty stderr, but got %q", stderrS)
			}
		})

		t.Run("should error if the context completes before the command", func(t *testing.T) {
			ctx, cancel := context.WithCancel(context.Background())
			cancel()

			r := Runner{}
			command := []string{"sleep", "5"}
			err := r.Run(ctx, command, nil, nil)
			if err == nil {
				t.Fatal("Expected sleep command to terminate early but it completed")
			} else if !errors.Is(err, ctx.Err()) {
				t.Fatalf("Expected Run() to return a context error after cancelation but got: %s", err)
			}
		})

		t.Run("should return an error if the command fails", func(t *testing.T) {
			r := Runner{}
			command := []string{"not_a_command_12345"}
			err := r.Run(context.Background(), command, nil, nil)
			if err == nil {
				t.Fatalf("Expected invalid command to fail but it succeeded: %s", err)
			} else if !errors.Is(err, exec.ErrNotFound) {
				t.Fatalf("Expected Run() to return exec.ErrNotFound but got: %s", err)
			}
		})

		t.Run("should wait for command to finish after sending SIGTERM", func(t *testing.T) {
			script := filepath.Join(t.TempDir(), "script")
			// The script below will print `start` to signify that it's ready to handle
			// SIGTERMs and SIGINTs and then run cleanup() when it receives the signal.
			// By checking that `start` is printed before canceling the context and checking
			// that `finished` is printed after, we can assert that the cleanup() function
			// was run before the script exited.
			if err := ioutil.WriteFile(script, []byte(
				`#!/bin/bash
				cleanup() {
					echo "finished"; exit 1
				}
				trap cleanup TERM INT
				echo "start"
				while true;do :; done`,
			), os.ModePerm); err != nil {
				t.Fatalf("Failed to write script: %s", err)
			}
			r := Runner{}
			command := []string{script}
			stdoutReader, stdout := io.Pipe()
			defer stdoutReader.Close()
			defer stdout.Close()
			ctx, cancel := context.WithCancel(context.Background())
			defer cancel()
			go func() {
				buf := make([]byte, 20)
				// Wait for script to print `start` before calling cancel() to know
				// that it's ready to handle the SIGTERM.
				if _, err := stdoutReader.Read(buf); err != nil || !bytes.Contains(buf, []byte("start")) {
					t.Errorf("Failed to read `start` from stdout: %s, got: %s", err, string(buf))
				}
				cancel()
				// After sending the SIGTERM, check that the script ran cleanup() and
				// printed `finished`.
				buf = make([]byte, 20)
				if _, err := stdoutReader.Read(buf); err != nil || !bytes.Contains(buf, []byte("finished")) {
					t.Errorf("Failed to read `finished` from stdout: %s, got: %s", err, string(buf))
				}
			}()
			if err := r.Run(ctx, command, stdout, stdout); err == nil {
				t.Errorf("Expected script to terminate early but it completed successfully")
			} else {
				var exitError *exec.ExitError
				if !errors.As(err, &exitError) {
					t.Errorf("Expected Run() to return exec.ExitError but got: %s", err)
				}
			}
		})

		t.Run("should kill command if it doesn't terminate after sending SIGTERM", func(t *testing.T) {
			if runtime.GOOS == "darwin" {
				// Setting the pgid doesn't work on Mac OS, so this test
				// will hang because it can't kill the sleep process.
				// TODO(fxbug.dev/86162): Enable if we can find a way to kill
				// the child processes.
				t.Skip("Skipping on Mac because setting pgid doesn't work")
			}
			script := filepath.Join(t.TempDir(), "script")
			// The script below will print `start` to signify that it's ready to handle
			// SIGTERMs and SIGINTs and then run cleanup() when it receives the signal.
			// However, since it starts a `sleep` process, it actually waits for the process
			// to finish before entering cleanup(). This will test that the process group
			// gets killed if it can't clean up and exit in time. In this test, `finished`
			// should not be in the output because the process would have been killed before
			// it could run cleanup().
			if err := ioutil.WriteFile(script, []byte(
				`#!/bin/bash
                                cleanup() {
					echo "finished"; exit 1
                                }
                                trap cleanup TERM INT
                                echo "start"
				sleep 10000`,
			), os.ModePerm); err != nil {
				t.Fatalf("Failed to write script: %s", err)
			}
			r := Runner{}
			command := []string{script}
			stdoutReader, stdout := io.Pipe()
			defer stdoutReader.Close()
			defer stdout.Close()
			fakeClock := clock.NewFakeClock()
			ctx := clock.NewContext(context.Background(), fakeClock)
			ctx, cancel := context.WithCancel(ctx)
			defer cancel()
			go func() {
				buf := make([]byte, 20)
				if _, err := stdoutReader.Read(buf); err != nil || !bytes.Contains(buf, []byte("start")) {
					t.Errorf("Failed to read `start` from stdout: %s, got: %s", err, string(buf))
				}
				cancel()
				// Wait for After() to be called before advancing the clock.
				<-fakeClock.AfterCalledChan()
				fakeClock.Advance(cleanupGracePeriod + time.Second)
				// The script should be killed before it reaches cleanup(), so `finished`
				// should NOT have been printed to stdout. No need to check the err from
				// Read() because we don't expect the script to print anything more to
				// stdout, so it should block until the deferred stdout.Close() gets
				// executed.
				buf = make([]byte, 20)
				stdoutReader.Read(buf)
				if bytes.Contains(buf, []byte("finished")) {
					t.Errorf("Expected script to be killed without doing cleanup")
				}
			}()
			if err := r.RunWithStdin(ctx, command, stdout, stdout, nil); err == nil {
				t.Errorf("Expected script to terminate early but it completed successfully")
			} else {
				var exitError *exec.ExitError
				if !errors.As(err, &exitError) {
					t.Errorf("Expected Run() to return exec.ExitError but got: %s", err)
				}
			}
		})
	})
}
