// 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 bisectConfig struct {
	*taskConfig
	failingHash string
	passingHash string
	isFix       bool
	fuzzerName  string
}

// 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)

	origRefBytes, err := bc.runCmd("git", "rev-parse", "--abbrev-ref", "HEAD")
	if err != nil {
		return fmt.Errorf("failed to get original HEAD reference: %w", err)
	}
	origRef := strings.TrimSpace(string(origRefBytes))
	if origRef == "HEAD" {
		origHeadBytes, err := bc.runCmd("git", "rev-parse", "HEAD")
		if err != nil {
			return fmt.Errorf("failed to get original HEAD commit: %w", err)
		}
		origRef = strings.TrimSpace(string(origHeadBytes))
	}

	// Ensure repository state restore upon completion
	defer func() {
		fmt.Printf("Restoring repository to original state (%s)...\n", origRef)
		_, _ = bc.runCmd("git", "checkout", origRef)
		_, _ = bc.runCmd("gclient", "sync")
	}()

	// 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
}

type syncBuildRunResult int

const (
	SyncBuildRunPassed syncBuildRunResult = iota
	SyncBuildRunFailed
	SyncBuildRunError // sync or build failed
)

// syncBuildRun runs gclient sync, builds the fuzzer, and runs the test case, returning the outcome.
// Note: is intentionally a receiver on taskConfig instead of bisectConfig, because bisectStep use/need the whole
//
//	bisectConfig state
func (t *taskConfig) syncBuildRun() (syncBuildRunResult, error) {
	fmt.Println("--> Running gclient sync...")
	if _, err := t.runCmd("gclient", "sync"); err != nil {
		return SyncBuildRunError, fmt.Errorf("gclient sync failed: %w", err)
	}

	fuzzerName := filepath.Base(t.fuzzer)
	fmt.Printf("--> Building fuzzer %s...\n", fuzzerName)
	if _, err := t.runCmd("autoninja", "-C", t.build, fuzzerName); err != nil {
		return SyncBuildRunError, fmt.Errorf("build failed: %w", err)
	}

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

// verifyCommit checks out a commit, calls syncBuildRun, and asserts that it matches the expected outcome.
func (bc *bisectConfig) verifyCommit(hash string, expectPass bool) error {
	if _, err := bc.runCmd("git", "checkout", hash); err != nil {
		return fmt.Errorf("failed to checkout %s: %w", hash, err)
	}

	result, err := bc.syncBuildRun()
	if result == SyncBuildRunError {
		return fmt.Errorf("execution at %s failed: %w", hash, err)
	}

	passed := result == SyncBuildRunPassed
	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}
	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
}

// runBisectStep implements a single git bisect step invoked by git bisect run.
// It calls syncBuildRun and returns an appropriate exit codes (0 for good, 1 for bad, 125 for skipped/unbuildable).
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 := t.syncBuildRun()
	if result == SyncBuildRunError {
		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 == SyncBuildRunPassed {
			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 == SyncBuildRunPassed {
			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"))
	}
}
