// Copyright 2022 The ChromiumOS Authors.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
)

// ** HEY YOU, PERSON READING THIS! **
//
// Are you a dev who wants to make this work locally? Awesome! Please note that this **only** works
// for Clang. If that's OK, here's a checklist for you:
// [ ] Set `shouldUseCrashBuildsHeuristic = true` below.
// [ ] If you want this heuristic to operate during `src_configure` (rare), also set
// `allowAutoCrashInConfigure` to true.
// [ ] Modify `shouldAutocrashPostExec` to return `true` when the compiler's output/flags match what
// you want to crash on, and `false` otherwise.
// [ ] Run `./install_compiler_wrapper.sh` to install the updated wrapper.
// [ ] Run whatever command reproduces the error.
//
// If you need to make changes to your heuristic, repeat the above steps starting at
// `./install_compiler_wrapper.sh` until things seem to do what you want.
const (
	// Set this to true to use autocrashing logic.
	shouldUseCrashBuildsHeuristic = false
	// Set this to true to allow `shouldAutocrashPostExec` to check+crash configure steps.
	allowAutoCrashInConfigure = false
)

// shouldAutocrashPostExec returns true if we should automatically crash the compiler. This is
// called after the compiler is run. If it returns true, we'll re-execute the compiler with the bit
// of extra code necessary to crash it.
func shouldAutocrashPostExec(env env, cfg *config, originalCmd *command, runInfo compilerExecInfo) bool {
	// ** TODO, DEAR READER: ** Fill this in. Below are a few `if false {` blocks that should
	// work for common use-cases. You're encouraged to change them to `if true {` if they suit
	// your needs.

	// Return true if `error: some error message` is contained in the run's stderr.
	if false {
		return bytes.Contains(runInfo.stderr, []byte("error: some error message"))
	}

	// Return true if `foo.c:${line_number}: error: some error message` appears in the run's
	// stderr. Otherwise, return false.
	if false {
		r := regexp.MustCompile(`foo\.c:\d+: error: some error message`)
		return r.Match(runInfo.stderr)
	}

	// Return true if there's a `-fjust-give-up` flag in the compiler's invocation.
	if false {
		for _, flag := range originalCmd.Args {
			if flag == "-fjust-give-up" {
				return true
			}
		}

		return false
	}

	panic("Please fill in `shouldAutocrashPostExec` with meaningful logic.")
}

type compilerExecInfo struct {
	exitCode       int
	stdout, stderr []byte
}

// ** Below here are implementation details. If all you want is autocrashing behavior, you don't
// need to keep reading. **
const (
	autocrashProgramLine = "\n#pragma clang __debug parser_crash"
)

type buildWithAutocrashPredicates struct {
	allowInConfigure bool
	shouldAutocrash  func(env, *config, *command, compilerExecInfo) bool
}

func buildWithAutocrash(env env, cfg *config, originalCmd *command) (exitCode int, err error) {
	return buildWithAutocrashImpl(env, cfg, originalCmd, buildWithAutocrashPredicates{
		allowInConfigure: allowAutoCrashInConfigure,
		shouldAutocrash:  shouldAutocrashPostExec,
	})
}

func buildWithAutocrashImpl(env env, cfg *config, originalCmd *command, preds buildWithAutocrashPredicates) (exitCode int, err error) {
	stdinBuffer := (*bytes.Buffer)(nil)
	subprocStdin := io.Reader(nil)
	invocationUsesStdinAsAFile := needStdinTee(originalCmd)
	if invocationUsesStdinAsAFile {
		stdinBuffer = &bytes.Buffer{}
		if _, err := stdinBuffer.ReadFrom(env.stdin()); err != nil {
			return 0, wrapErrorwithSourceLocf(err, "prebuffering stdin")
		}
		subprocStdin = stdinBuffer
	} else {
		subprocStdin = env.stdin()
	}

	stdoutBuffer := &bytes.Buffer{}
	stderrBuffer := &bytes.Buffer{}
	exitCode, err = wrapSubprocessErrorWithSourceLoc(originalCmd,
		env.run(originalCmd, subprocStdin, stdoutBuffer, stderrBuffer))
	if err != nil {
		return 0, err
	}

	autocrashAllowed := preds.allowInConfigure || !isInConfigureStage(env)
	crash := autocrashAllowed && preds.shouldAutocrash(env, cfg, originalCmd, compilerExecInfo{
		exitCode: exitCode,
		stdout:   stdoutBuffer.Bytes(),
		stderr:   stderrBuffer.Bytes(),
	})
	if !crash {
		stdoutBuffer.WriteTo(env.stdout())
		stderrBuffer.WriteTo(env.stderr())
		return exitCode, nil
	}

	fmt.Fprintln(env.stderr(), "** Autocrash requested; crashing the compiler...**")

	// `stdinBuffer == nil` implies that `-` wasn't used as a flag.  If `-` isn't used as a
	// flag, clang will ignore stdin. We want to write our #pragma to stdin, since we can't
	// reasonably modify the files we're currently compiling.
	if stdinBuffer == nil {
		newArgs := []string{}
		// Clang can't handle `-o ${target}` when handed multiple input files. Since
		// we expect to crash before emitting anything, remove `-o ${file}` entirely.
		for i, e := 0, len(originalCmd.Args); i < e; i++ {
			a := originalCmd.Args[i]
			if a == "-o" {
				// Skip the -o here, then skip the following arg in the loop header.
				i++
			} else {
				newArgs = append(newArgs, a)
			}
		}
		// And now add args that instruct clang to read from stdin. In this case, we also
		// need to tell Clang what language the file is written in; C is as good as anything
		// for this.
		originalCmd.Args = append(newArgs, "-x", "c", "-")
		stdinBuffer = &bytes.Buffer{}
	}

	stdinBuffer.WriteString(autocrashProgramLine)
	return wrapSubprocessErrorWithSourceLoc(originalCmd,
		env.run(originalCmd, stdinBuffer, env.stdout(), env.stderr()))
}
