// Copyright 2026 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this
//     list of conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"dawn.googlesource.com/dawn/tools/src/execwrapper"
	"dawn.googlesource.com/dawn/tools/src/fileutils"
)

// TODO(crbug.com/416755658): Add unittest coverage when exec calls are done
// via dependency injection.

type bisectStepResult int

const (
	BisectStepPassed bisectStepResult = iota
	BisectStepFailed
	BisectStepError // sync or build failed
)

type bisectConfig struct {
	*taskConfig
	failingHash string
	passingHash string
	isFix       bool
	fuzzerName  string
}

// verifyCommit checks out a commit, calls testBisectStep, and asserts that it matches the expected outcome.
func (bc *bisectConfig) verifyCommit(hash string, expectPass bool) error {
	var passed bool
	err := bc.atGitHash(hash, func() error {
		result, err := testBisectStep(bc.taskConfig)
		if err != nil {
			return err
		}
		passed = result == BisectStepPassed
		return nil
	})

	if err != nil {
		return fmt.Errorf("execution at %s failed: %w", hash, err)
	}

	if passed != expectPass {
		return fmt.Errorf("fuzzer execution returned pass=%v, but expected pass=%v", passed, expectPass)
	}
	return nil
}

// performBisect executes the standard git bisect routine by launching the current tool as an internal step subcommand.
func (bc *bisectConfig) performBisect() error {
	// Guarantee git bisect reset is called when bisection finishes
	defer func() {
		_, _ = bc.runCmd("git", "bisect", "reset")
	}()

	if _, err := bc.runCmd("git", "bisect", "start"); err != nil {
		return fmt.Errorf("failed to start git bisect: %w", err)
	}

	var err error
	if bc.isFix {
		// "bad" in git bisect is the target state we want to identify (the fix).
		// "good" in git bisect is the starting/original state (the breakage).
		_, err = bc.runCmd("git", "bisect", "bad", bc.passingHash)
		if err == nil {
			_, err = bc.runCmd("git", "bisect", "good", bc.failingHash)
		}
	} else {
		// "bad" in git bisect is the target state (the breakage).
		// "good" in git bisect is the working state (the passing).
		_, err = bc.runCmd("git", "bisect", "bad", bc.failingHash)
		if err == nil {
			_, err = bc.runCmd("git", "bisect", "good", bc.passingHash)
		}
	}
	if err != nil {
		return fmt.Errorf("failed to assign good/bad bounds to git bisect: %w", err)
	}

	self, err := os.Executable()
	if err != nil {
		return fmt.Errorf("failed to get absolute path of self: %w", err)
	}

	// Construct args to call ourselves back as the bisect-step handler
	args := []string{"bisect", "run", self, "-bisect-step", "-bisect=" + bc.bisectFile, "-build=" + bc.build}
	args = append(args, fmt.Sprintf("-timeout=%d", bc.timeout))
	if bc.isFix {
		args = append(args, "-is-fix")
	}
	if bc.fuzzMode == FuzzModeIr {
		args = append(args, "-ir")
	}
	if bc.mesaMode {
		args = append(args, "-mesa")
	}
	if bc.verbose {
		args = append(args, "-verbose")
	}

	// Execute git bisect run
	if err := bc.runCmdUnbuffered("git", args...); err != nil {
		return fmt.Errorf("git bisect run failed: %w", err)
	}

	// Git bisect leaves refs/bisect/bad pointing to the identified commit.
	// Query refs/bisect/bad to fetch the exact found commit hash.
	if foundHashBytes, err := bc.runCmd("git", "rev-parse", "refs/bisect/bad"); err == nil {
		foundHash := strings.TrimSpace(string(foundHashBytes))
		bannerText := "FOUND BREAKAGE"
		if bc.isFix {
			bannerText = "FOUND FIX"
		}
		fmt.Println("\n================================================================================")
		fmt.Printf("%s @ %s\n", bannerText, foundHash)
		if logBytes, err := bc.runCmd("git", "log", "-1", "--oneline", foundHash); err == nil {
			fmt.Printf("%s", string(logBytes))
		}
		fmt.Println("================================================================================")
		fmt.Println()
	}

	return nil
}

// runBisect orchestrates the automated bisection of a fuzzer testcase.
// It verifies that both passing and failing points behave as expected and then executes a git bisect run.
func runBisect(t *taskConfig) error {
	if t.bisectFile == "" {
		return fmt.Errorf("-bisect flag requires a test case file path")
	}
	if t.knownFailing == "" {
		return fmt.Errorf("-known-failing flag is required when bisecting")
	}

	if !t.skipInputTypeCheck {
		if err := checkInputFileType(t.bisectFile, t.fuzzMode, t.osWrapper); err != nil {
			return err
		}
	}

	bc := &bisectConfig{taskConfig: t}

	bc.fuzzerName = filepath.Base(t.fuzzer)

	// Verify build directory exists and is a GN build (contains args.gn)
	argsGnPath := filepath.Join(t.build, "args.gn")
	if !fileutils.IsFile(argsGnPath, t.osWrapper) {
		return fmt.Errorf("build directory '%v' does not appear to be a GN build directory (missing args.gn), which is required for bisecting", t.build)
	}

	var err error
	failingEP, err := resolveEndpoint(bc.knownFailing, bc.execWrapper)
	if err != nil {
		return fmt.Errorf("failed to resolve known-failing '%s': %w", bc.knownFailing, err)
	}

	passingEP, err := resolveEndpoint(bc.knownPassing, bc.execWrapper)
	if err != nil {
		return fmt.Errorf("failed to resolve known-passing '%s': %w", bc.knownPassing, err)
	}

	if failingEP.timestamp.Before(passingEP.timestamp) {
		bc.isFix = true
		fmt.Println("Detected flow: FAILING commit is older than PASSING commit (looking for the FIX).")
	} else if passingEP.timestamp.Before(failingEP.timestamp) {
		bc.isFix = false
		fmt.Println("Detected flow: PASSING commit is older than FAILING commit (looking for the BREAKAGE).")
	} else {
		return fmt.Errorf("failing and passing endpoints resolve to the same time (%v), cannot bisect", failingEP.timestamp)
	}

	// Resolve the endpoints to final exact hashes based on older/newer boundary roles
	bc.failingHash, err = resolveEndpointToHash(failingEP, bc.isFix, bc.execWrapper)
	if err != nil {
		return fmt.Errorf("failed to resolve known-failing date bound: %w", err)
	}

	bc.passingHash, err = resolveEndpointToHash(passingEP, !bc.isFix, bc.execWrapper)
	if err != nil {
		return fmt.Errorf("failed to resolve known-passing date bound: %w", err)
	}

	fmt.Printf("Resolved known-failing to commit: %s\n", bc.failingHash)
	fmt.Printf("Resolved known-passing to commit: %s\n", bc.passingHash)

	// Determine lineage
	mergeBaseBytes, err := bc.runCmd("git", "merge-base", bc.failingHash, bc.passingHash)
	if err != nil {
		return fmt.Errorf("failed to find merge-base between %s and %s: %w", bc.failingHash, bc.passingHash, err)
	}
	mergeBase := strings.TrimSpace(string(mergeBaseBytes))

	if bc.isFix {
		if mergeBase != bc.failingHash {
			return fmt.Errorf("the failing commit (%s) and passing commit (%s) are not in a direct ancestral relationship (merge-base is %s)", bc.failingHash, bc.passingHash, mergeBase)
		}
	} else {
		if mergeBase != bc.passingHash {
			return fmt.Errorf("the passing commit (%s) and failing commit (%s) are not in a direct ancestral relationship (merge-base is %s)", bc.passingHash, bc.failingHash, mergeBase)
		}
	}

	// Verify failing commit behaves as expected
	fmt.Printf("Verifying known-failing commit (%s)...\n", bc.failingHash)
	if err := bc.verifyCommit(bc.failingHash, false); err != nil {
		return fmt.Errorf("verification of known-failing commit %s failed: %w", bc.failingHash, err)
	}
	fmt.Println("Verification succeeded: fuzzer failed on known-failing commit as expected.")

	// Verify passing commit behaves as expected
	fmt.Printf("Verifying known-passing commit (%s)...\n", bc.passingHash)
	if err := bc.verifyCommit(bc.passingHash, true); err != nil {
		return fmt.Errorf("verification of known-passing commit %s failed: %w", bc.passingHash, err)
	}
	fmt.Println("Verification succeeded: fuzzer passed on known-passing commit as expected.")

	// Run bisection
	fmt.Println("Both bounds verified. Commencing bisection...")
	if err := bc.performBisect(); err != nil {
		return fmt.Errorf("bisection failed: %w", err)
	}

	return nil
}

// testBisectStep runs gclient sync, builds t.fuzzer, and runs the test case, returning the outcome.
func testBisectStep(t *taskConfig) (bisectStepResult, error) {
	fuzzerName := filepath.Base(t.fuzzer)
	if err := t.syncAndBuildTargets([]string{fuzzerName}); err != nil {
		return BisectStepError, err
	}

	fmt.Printf("--> Running fuzzer %s against test case...\n", fuzzerName)
	_, err := t.runCmd(t.fuzzer, fmt.Sprintf("-timeout=%d", t.timeout), t.bisectFile)
	if err != nil {
		return BisectStepFailed, nil
	}
	return BisectStepPassed, nil
}

// runBisectStep implements a single git bisect step invoked by git bisect run.
// It calls syncBuildAndRun and returns an appropriate exit codes (0 for good, 1 for bad, 125 for skipped/unbuildable).
// It intentionally does not use atGitHash, because git bisect should be managing the repo state.
func runBisectStep(t *taskConfig) error {
	fmt.Print("Running bisect step for commit: ")
	if out, err := t.runCmd("git", "rev-parse", "HEAD"); err == nil {
		fmt.Printf("%s", string(out))
	} else {
		fmt.Println("unknown")
	}

	result, err := testBisectStep(t)
	if err != nil {
		fmt.Printf("Step execution failed: %v. Skipping commit.\n", err)
		t.exitFn(125)
		return nil
	}

	// Translate to git bisect exit code
	if t.isFix {
		if result == BisectStepPassed {
			fmt.Println("Fuzzer passed. This commit has the fix (bad for bisect).")
			t.exitFn(1)
		} else {
			fmt.Println("Fuzzer failed. This commit does NOT have the fix (good for bisect).")
			t.exitFn(0)
		}
	} else {
		if result == BisectStepPassed {
			fmt.Println("Fuzzer passed. This commit does NOT have the breakage (good for bisect).")
			t.exitFn(0)
		} else {
			fmt.Println("Fuzzer failed. This commit has the breakage (bad for bisect).")
			t.exitFn(1)
		}
	}

	return nil
}

type endpoint struct {
	timestamp time.Time
	isDate    bool
	dateStr   string
	hash      string
}

// getRepoLocation retrieves the timezone location of the HEAD commit of the repository.
func getRepoLocation(execWrapper execwrapper.ExecWrapper) (*time.Location, error) {
	out, err := execWrapper.Command("git", "log", "-1", "--format=%cI", "HEAD").RunWithCombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to get commit time of HEAD: %w", err)
	}
	timeStr := strings.TrimSpace(string(out))
	parsedTime, err := time.Parse(time.RFC3339, timeStr)
	if err != nil {
		return nil, fmt.Errorf("failed to parse HEAD commit time %s: %w", timeStr, err)
	}
	return parsedTime.Location(), nil
}

// resolveEndpoint parses an input string to determine if it is a hash or a date.
func resolveEndpoint(input string, execWrapper execwrapper.ExecWrapper) (*endpoint, error) {
	if input == "" {
		input = "HEAD"
	}

	// Try treating it as a hash or ref first
	out, err := execWrapper.Command("git", "rev-parse", "--verify", input+"^{commit}").RunWithCombinedOutput()
	if err == nil {
		hash := strings.TrimSpace(string(out))
		out, err = execWrapper.Command("git", "log", "-1", "--format=%cI", hash).RunWithCombinedOutput()
		if err != nil {
			return nil, fmt.Errorf("failed to get commit time for %s: %w", hash, err)
		}
		timeStr := strings.TrimSpace(string(out))
		parsedTime, err := time.Parse(time.RFC3339, timeStr)
		if err != nil {
			return nil, fmt.Errorf("failed to parse commit time %s: %w", timeStr, err)
		}
		return &endpoint{hash: hash, timestamp: parsedTime}, nil
	}

	// Get repo location based on HEAD timezone to interpret input dates consistently with repo history
	repoLoc, err := getRepoLocation(execWrapper)
	if err != nil {
		repoLoc = time.Local
	}

	// Strictly require YYYY-MM-DD format for imprecise dates
	parsedTime, err := time.ParseInLocation("2006-01-02", input, repoLoc)
	if err != nil {
		return nil, fmt.Errorf("could not resolve '%s' as a git ref, and it does not match required YYYY-MM-DD date format", input)
	}

	return &endpoint{
		isDate:    true,
		dateStr:   input,
		timestamp: parsedTime,
	}, nil
}

// resolveEndpointToHash resolves an endpoint to an exact git commit hash based on whether it is the older or newer bound.
func resolveEndpointToHash(ep *endpoint, isOlderBound bool, execWrapper execwrapper.ExecWrapper) (string, error) {
	if !ep.isDate {
		return ep.hash, nil
	}

	if isOlderBound {
		// Older bound date: want the last hash of the previous day, i.e. last commit BEFORE the date D (D 00:00:00).
		timeStr := ep.timestamp.Format(time.RFC3339)
		out, err := execWrapper.Command("git", "log", "-1", "--format=%H", "--before="+timeStr).RunWithCombinedOutput()
		if err != nil {
			return "", fmt.Errorf("failed to get last commit before %s: %w (output: %s)", timeStr, err, strings.TrimSpace(string(out)))
		}
		hash := strings.TrimSpace(string(out))
		if hash == "" {
			return "", fmt.Errorf("no commits found before %s", ep.dateStr)
		}
		return hash, nil
	} else {
		// Newer bound date: want the first hash of the next day, i.e. first commit ON or AFTER (D + 1 day).
		nextDay := ep.timestamp.AddDate(0, 0, 1)
		timeStr := nextDay.Format(time.RFC3339)
		out, err := execWrapper.Command("git", "log", "--format=%H", "--since="+timeStr, "--reverse").RunWithCombinedOutput()
		if err != nil {
			return "", fmt.Errorf("failed to get commits since %s: %w (output: %s)", timeStr, err, strings.TrimSpace(string(out)))
		}
		lines := strings.Split(strings.TrimSpace(string(out)), "\n")
		if len(lines) > 0 && lines[0] != "" {
			return lines[0], nil
		}
		return "", fmt.Errorf("no commits found on or after next day %s", nextDay.Format("2006-01-02"))
	}
}
