package app

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

const singleTicketAfterReplayFile = ".auto-oncall-single-ticket-after-replay.json"

const (
	pullRequestChecksRegistrationTimeout  = 2 * time.Minute
	pullRequestChecksRegistrationInterval = 2 * time.Second
)

type singleTicketReplayAssessment struct {
	SchemaVersion string   `json:"schemaVersion"`
	Outcome       string   `json:"outcome"`
	Reason        string   `json:"reason"`
	EvidenceRefs  []string `json:"evidenceRefs"`
}

type githubWorkflowRun struct {
	DatabaseID int64  `json:"databaseId"`
	HeadSHA    string `json:"headSha"`
	Status     string `json:"status"`
	Conclusion string `json:"conclusion"`
}

type singleTicketPublicationVerification struct {
	RunID      string
	RunDBID    int64
	CommentID  string
	CommentURL string
}

func (r *CodexRunner) mergeAndDeploySingleTicket(ctx context.Context, worktree, prURL string) (string, error) {
	if !r.config.AutoMergeEnabled {
		return "", errors.New("single-ticket automatic merge is disabled")
	}
	if err := waitForPullRequestChecks(ctx, pullRequestChecksRegistrationTimeout, pullRequestChecksRegistrationInterval, func() error {
		_, err := r.command(ctx, worktree, r.config.GitHubBin, pullRequestChecksArgs(prURL, r.config.GitHubRepo)...)
		return err
	}); err != nil {
		return "", fmt.Errorf("wait single-ticket pull request checks: %w", err)
	}
	if _, err := r.command(ctx, worktree, r.config.GitHubBin, "pr", "merge", prURL,
		"--repo", r.config.GitHubRepo, "--squash", "--delete-branch"); err != nil {
		return "", fmt.Errorf("merge single-ticket pull request without human review: %w", err)
	}
	viewRaw, err := r.command(ctx, worktree, r.config.GitHubBin, "pr", "view", prURL,
		"--repo", r.config.GitHubRepo, "--json", "state,mergeCommit")
	if err != nil {
		return "", fmt.Errorf("read merged single-ticket pull request: %w", err)
	}
	mergeSHA, err := mergedPullRequestSHA([]byte(viewRaw))
	if err != nil {
		return "", err
	}
	deploySHA, err := r.fetchFreshMain(ctx)
	if err != nil {
		return "", fmt.Errorf("fetch merged main before deployment: %w", err)
	}
	if _, err := r.command(ctx, r.config.RepoPath, "git", "merge-base", "--is-ancestor", mergeSHA, "origin/main"); err != nil {
		return "", fmt.Errorf("merged repair is not present on origin/main: %w", err)
	}
	if err := r.dispatchAndWaitDeploymentWorkflow(ctx, worktree, deploySHA); err != nil {
		return "", err
	}
	if err := r.waitForAnalysisBuildSHA(ctx, deploySHA); err != nil {
		return "", err
	}
	return deploySHA, nil
}

func pullRequestChecksArgs(prURL, repo string) []string {
	return []string{"pr", "checks", prURL, "--repo", repo, "--watch"}
}

func deploymentWorkflowRunsArgs(repo, workflow string) []string {
	return []string{
		"run", "list", "--repo", repo, "--workflow", workflow,
		"--limit", "20", "--json", "databaseId,headSha,status,conclusion",
	}
}

func waitForPullRequestChecks(ctx context.Context, registrationTimeout, registrationInterval time.Duration, check func() error) error {
	deadline := time.Now().Add(registrationTimeout)
	for {
		err := check()
		if err == nil {
			return nil
		}
		if !strings.Contains(err.Error(), "no checks reported on the") {
			return err
		}
		if !time.Now().Before(deadline) {
			return fmt.Errorf("pull request checks did not register within %s: %w", registrationTimeout, err)
		}
		if err := waitContext(ctx, min(registrationInterval, time.Until(deadline))); err != nil {
			return err
		}
	}
}

func mergedPullRequestSHA(payload []byte) (string, error) {
	var view struct {
		State       string `json:"state"`
		MergeCommit *struct {
			OID string `json:"oid"`
		} `json:"mergeCommit"`
	}
	if err := json.Unmarshal(payload, &view); err != nil {
		return "", fmt.Errorf("decode merged pull request state: %w", err)
	}
	if view.State != "MERGED" || view.MergeCommit == nil || len(strings.TrimSpace(view.MergeCommit.OID)) < 7 {
		return "", fmt.Errorf("pull request did not reach merged state")
	}
	return strings.TrimSpace(view.MergeCommit.OID), nil
}

func (r *CodexRunner) dispatchAndWaitDeploymentWorkflow(ctx context.Context, worktree, deploySHA string) error {
	before, err := r.listDeploymentWorkflowRuns(ctx, worktree)
	if err != nil {
		return err
	}
	known := make(map[int64]struct{}, len(before))
	for _, run := range before {
		known[run.DatabaseID] = struct{}{}
	}
	if _, err := r.command(ctx, worktree, r.config.GitHubBin, "workflow", "run", r.config.DeploymentWorkflow,
		"--repo", r.config.GitHubRepo, "--ref", "main"); err != nil {
		return fmt.Errorf("dispatch auto-oncall staging deployment: %w", err)
	}
	deadline := time.Now().Add(r.config.DeploymentTimeout)
	var targetID int64
	for time.Now().Before(deadline) {
		runs, listErr := r.listDeploymentWorkflowRuns(ctx, worktree)
		if listErr != nil {
			return listErr
		}
		for _, run := range runs {
			if _, existed := known[run.DatabaseID]; !existed && run.HeadSHA == deploySHA {
				targetID = run.DatabaseID
				break
			}
		}
		if targetID != 0 {
			break
		}
		if err := waitContext(ctx, r.config.DeploymentPollInterval); err != nil {
			return err
		}
	}
	if targetID == 0 {
		return fmt.Errorf("deployment workflow run for %s was not discovered before timeout", deploySHA)
	}
	for time.Now().Before(deadline) {
		raw, viewErr := r.command(ctx, worktree, r.config.GitHubBin, "run", "view", strconv.FormatInt(targetID, 10),
			"--repo", r.config.GitHubRepo, "--json", "databaseId,headSha,status,conclusion")
		if viewErr != nil {
			return fmt.Errorf("read deployment workflow run %d: %w", targetID, viewErr)
		}
		var run githubWorkflowRun
		if err := json.Unmarshal([]byte(raw), &run); err != nil {
			return fmt.Errorf("decode deployment workflow run %d: %w", targetID, err)
		}
		if run.Status == "completed" {
			if run.Conclusion != "success" {
				return fmt.Errorf("deployment workflow run %d completed with %s", targetID, run.Conclusion)
			}
			return nil
		}
		if err := waitContext(ctx, r.config.DeploymentPollInterval); err != nil {
			return err
		}
	}
	return fmt.Errorf("deployment workflow run %d did not complete before timeout", targetID)
}

func (r *CodexRunner) listDeploymentWorkflowRuns(ctx context.Context, worktree string) ([]githubWorkflowRun, error) {
	raw, err := r.command(ctx, worktree, r.config.GitHubBin,
		deploymentWorkflowRunsArgs(r.config.GitHubRepo, r.config.DeploymentWorkflow)...)
	if err != nil {
		return nil, fmt.Errorf("list staging deployment workflow runs: %w", err)
	}
	var runs []githubWorkflowRun
	if err := json.Unmarshal([]byte(raw), &runs); err != nil {
		return nil, fmt.Errorf("decode staging deployment workflow runs: %w", err)
	}
	return runs, nil
}

func (r *CodexRunner) waitForAnalysisBuildSHA(ctx context.Context, expectedSHA string) error {
	deadline := time.Now().Add(r.config.DeploymentTimeout)
	client := &http.Client{Transport: http.DefaultTransport, Timeout: 15 * time.Second}
	for time.Now().Before(deadline) {
		req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.config.AnalysisBaseURL+"/", nil)
		if err != nil {
			return err
		}
		resp, requestErr := client.Do(req)
		if requestErr == nil {
			payload, readErr := io.ReadAll(io.LimitReader(resp.Body, 1024*1024))
			resp.Body.Close()
			if readErr == nil && resp.StatusCode >= 200 && resp.StatusCode < 300 {
				var metadata struct {
					BuildSHA string `json:"buildSha"`
				}
				if json.Unmarshal(payload, &metadata) == nil && metadata.BuildSHA == expectedSHA {
					return nil
				}
			}
		}
		if err := waitContext(ctx, r.config.DeploymentPollInterval); err != nil {
			return err
		}
	}
	return fmt.Errorf("auto-oncall analysis service did not reach build SHA %s before timeout", expectedSHA)
}

func (r *CodexRunner) requestSingleTicketReplay(ctx context.Context, issueKey, mode string) ([]byte, int, error) {
	payload, err := json.Marshal(map[string]string{"issueKey": issueKey, "mode": mode})
	if err != nil {
		return nil, 0, err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, r.config.AnalysisBaseURL+"/v1/tickets/analyze", strings.NewReader(string(payload)))
	if err != nil {
		return nil, 0, err
	}
	req.Header.Set("content-type", "application/json")
	resp, err := (&http.Client{Transport: http.DefaultTransport}).Do(req)
	if err != nil {
		return nil, 0, fmt.Errorf("run post-deployment %s replay: %w", mode, err)
	}
	defer resp.Body.Close()
	response, err := io.ReadAll(io.LimitReader(resp.Body, 4*1024*1024+1))
	if err != nil {
		return nil, 0, err
	}
	if len(response) > 4*1024*1024 {
		return nil, 0, errors.New("post-deployment replay response exceeds 4 MiB")
	}
	return response, resp.StatusCode, nil
}

func (r *CodexRunner) publishSingleTicketReadReplay(ctx context.Context, issueKey, readRunID string) ([]byte, int, error) {
	payload, err := json.Marshal(map[string]string{"issueKey": issueKey, "readRunId": readRunID})
	if err != nil {
		return nil, 0, err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, r.config.AnalysisBaseURL+"/v1/tickets/publish-read", strings.NewReader(string(payload)))
	if err != nil {
		return nil, 0, err
	}
	req.Header.Set("content-type", "application/json")
	resp, err := (&http.Client{Transport: http.DefaultTransport}).Do(req)
	if err != nil {
		return nil, 0, fmt.Errorf("publish post-deployment read replay: %w", err)
	}
	defer resp.Body.Close()
	response, err := io.ReadAll(io.LimitReader(resp.Body, 4*1024*1024+1))
	if err != nil {
		return nil, 0, err
	}
	if len(response) > 4*1024*1024 {
		return nil, 0, errors.New("read replay publication response exceeds 4 MiB")
	}
	return response, resp.StatusCode, nil
}

func (r *CodexRunner) assessSingleTicketReplay(
	ctx context.Context,
	job Job,
	worktree string,
	investigation *SingleTicketInvestigation,
	replay []byte,
) (*singleTicketReplayAssessment, string, error) {
	if err := os.WriteFile(filepath.Join(worktree, singleTicketAfterReplayFile), append(replay, '\n'), 0o400); err != nil {
		return nil, "", fmt.Errorf("write post-deployment replay evidence: %w", err)
	}
	selected := investigation.selectedRepairFinding()
	if selected == nil {
		return nil, "", errors.New("post-deployment replay assessment requires one selected finding")
	}
	prompt := fmt.Sprintf(`You are the read-only verification Agent for the already merged single-ticket repair for %s.
Read %s and %s. Evaluate only the selected finding %s and its exact acceptance criterion: %s.

Return passed only when the post-deployment replay directly proves that criterion on the deployed build and does not reproduce the nominated signal. Return small_repairable only when the remaining failure is the same finding, same earliest owner, and can be fixed by one local change within the already admitted implementation targets. Return human_handoff for a new finding, changed owner or stage, cross-case diagnostic judgment, external/transient uncertainty, unsafe write, or any scope expansion. A successful HTTP response alone is not proof. runnerNotices are operational evidence, not diagnosis evidence.

Do not change files or call external systems. Return only JSON matching the schema.`,
		job.IssueKey, singleTicketInvestigationFile, singleTicketAfterReplayFile, selected.ID, pointerValue(selected.RepairDecision.AcceptanceCriterion))
	raw, threadID, err := r.runCodex(ctx, job, worktree, prompt, false, singleTicketReplayAssessmentSchema(), "replay-assessment")
	if err != nil {
		return nil, threadID, err
	}
	var assessment singleTicketReplayAssessment
	if err := json.Unmarshal([]byte(raw), &assessment); err != nil {
		return nil, threadID, fmt.Errorf("decode post-deployment replay assessment: %w", err)
	}
	if assessment.SchemaVersion != "auto-oncall-single-ticket-replay-assessment-v1" ||
		(assessment.Outcome != "passed" && assessment.Outcome != "small_repairable" && assessment.Outcome != "human_handoff") ||
		strings.TrimSpace(assessment.Reason) == "" {
		return nil, threadID, errors.New("post-deployment replay assessment is invalid")
	}
	return &assessment, threadID, nil
}

func (r *CodexRunner) continueSingleTicketRepairAfterReplay(
	ctx context.Context,
	job Job,
	investigation *SingleTicketInvestigation,
	repairThreadID string,
	replay []byte,
	assessment *singleTicketReplayAssessment,
	originalRepairPaths []string,
) (string, string, string, string, error) {
	selected := investigation.selectedRepairFinding()
	if selected == nil || repairThreadID == "" || assessment == nil || assessment.Outcome != "small_repairable" {
		return "", "", "", "", errors.New("bounded replay repair is unavailable")
	}
	baseSHA, err := r.fetchFreshMain(ctx)
	if err != nil {
		return "", "", "", "", fmt.Errorf("fetch main for bounded replay repair: %w", err)
	}
	worktree := filepath.Join(r.config.WorkspaceRoot, job.ID+"-replay-repair")
	branch := "auto-oncall/ticket-" + strings.ToLower(job.IssueKey) + "-replay-" + job.ID
	if err := r.git(ctx, r.config.RepoPath, "worktree", "add", "-b", branch, worktree, "origin/main"); err != nil {
		return "", "", "", "", fmt.Errorf("create bounded replay repair worktree: %w", err)
	}
	if err := r.verifyWorktreeBase(ctx, worktree, baseSHA); err != nil {
		return "", "", worktree, branch, err
	}
	investigationJSON, err := json.MarshalIndent(investigation, "", "  ")
	if err != nil {
		return "", "", worktree, branch, err
	}
	if err := os.WriteFile(filepath.Join(worktree, singleTicketInvestigationFile), append(investigationJSON, '\n'), 0o400); err != nil {
		return "", "", worktree, branch, err
	}
	if err := os.WriteFile(filepath.Join(worktree, singleTicketAfterReplayFile), append(replay, '\n'), 0o400); err != nil {
		return "", "", worktree, branch, err
	}
	prompt := fmt.Sprintf(`The already merged repair for %s had one post-deployment replay gap classified as small_repairable:

%s

Continue the existing repair once. Read %s and %s. Change only the same selected finding %s, the same owner %s, and the previously admitted implementation targets: %s. Do not add a new finding, stage, owner, fallback, credential, ticket-specific behavior, broad diagnostic strategy, or unrelated cleanup. If the replay gap cannot be fixed inside that exact boundary, make no changes and say that human handoff is required.

Run focused tests and the complete repository test command. Do not commit, push, merge, deploy, write Jira, or modify optimization status; the controller owns those effects.`,
		job.IssueKey, assessment.Reason, singleTicketInvestigationFile, singleTicketAfterReplayFile,
		selected.ID, pointerValue(selected.RepairDecision.OwnerBoundary), strings.Join(selected.RepairDecision.ImplementationTargets, ", "))
	message, _, err := r.runCodexContinuation(
		ctx, job, worktree, prompt, true, nil, "post-replay-repair", repairThreadID,
	)
	if err != nil {
		return "", "", worktree, branch, err
	}
	_ = os.Chmod(filepath.Join(worktree, singleTicketInvestigationFile), 0o600)
	_ = os.Remove(filepath.Join(worktree, singleTicketInvestigationFile))
	_ = os.Chmod(filepath.Join(worktree, singleTicketAfterReplayFile), 0o600)
	_ = os.Remove(filepath.Join(worktree, singleTicketAfterReplayFile))
	paths, err := changedPaths(ctx, worktree)
	if err != nil {
		return "", "", worktree, branch, err
	}
	if err := validatePostReplayRepairPaths(paths, originalRepairPaths, selected.RepairDecision.ImplementationTargets); err != nil {
		return "", "", worktree, branch, err
	}
	if err := r.validateSingleTicketCandidate(ctx, worktree); err != nil {
		return "", "", worktree, branch, fmt.Errorf("validate bounded post-replay repair: %w", err)
	}
	if err := r.git(ctx, worktree, "add", "--", "auto-oncall-services"); err != nil {
		return "", "", worktree, branch, err
	}
	if err := r.git(ctx, worktree, "-c", "user.name=Auto Oncall Optimizer", "-c", "user.email=auto-oncall-optimizer@pingcap.com",
		"commit", "-m", singleTicketPRTitle(job)+" after replay"); err != nil {
		return "", "", worktree, branch, fmt.Errorf("commit bounded post-replay repair: %w", err)
	}
	if err := r.git(ctx, worktree, "push", "-u", "origin", branch); err != nil {
		return "", "", worktree, branch, fmt.Errorf("push bounded post-replay repair: %w", err)
	}
	prURL, err := r.command(ctx, worktree, r.config.GitHubBin, "pr", "create", "--repo", r.config.GitHubRepo,
		"--base", "main", "--head", branch, "--title", singleTicketPRTitle(job)+" after replay",
		"--body", fmt.Sprintf("Single-ticket job `%s` continued the same admitted finding after deployed replay.\n\n%s", job.ID, truncate(message, 10000)))
	if err != nil {
		return "", "", worktree, branch, fmt.Errorf("create bounded post-replay repair pull request: %w", err)
	}
	prURL = strings.TrimSpace(prURL)
	mergeSHA, err := r.mergeAndDeploySingleTicket(ctx, worktree, prURL)
	if err != nil {
		return prURL, "", worktree, branch, err
	}
	if err := os.WriteFile(filepath.Join(worktree, singleTicketInvestigationFile), append(investigationJSON, '\n'), 0o400); err != nil {
		return prURL, mergeSHA, worktree, branch, err
	}
	return prURL, mergeSHA, worktree, branch, nil
}

func validatePostReplayRepairPaths(paths, originalRepairPaths, implementationTargets []string) error {
	if len(paths) == 0 {
		return errors.New("bounded post-replay repair made no change")
	}
	allowedExact := map[string]struct{}{}
	for _, path := range append(append([]string{}, originalRepairPaths...), implementationTargets...) {
		allowedExact[filepath.ToSlash(filepath.Clean(path))] = struct{}{}
	}
	changedOwner := false
	for _, path := range paths {
		clean := filepath.ToSlash(filepath.Clean(path))
		if _, ok := allowedExact[clean]; ok {
			changedOwner = true
			continue
		}
		if strings.HasPrefix(clean, "auto-oncall-services/test/") {
			continue
		}
		return fmt.Errorf("bounded post-replay repair changed a new target: %s", clean)
	}
	if !changedOwner {
		return errors.New("bounded post-replay repair changed tests only")
	}
	return nil
}

func singleTicketReplayAssessmentSchema() map[string]any {
	return map[string]any{
		"type":                 "object",
		"additionalProperties": false,
		"required":             []string{"schemaVersion", "outcome", "reason", "evidenceRefs"},
		"properties": map[string]any{
			"schemaVersion": map[string]any{"type": "string", "const": "auto-oncall-single-ticket-replay-assessment-v1"},
			"outcome":       map[string]any{"type": "string", "enum": []string{"passed", "small_repairable", "human_handoff"}},
			"reason":        map[string]any{"type": "string", "minLength": 1},
			"evidenceRefs":  map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
		},
	}
}

func readReplayRunID(payload []byte, status int, issueKey string) (string, error) {
	if status < 200 || status >= 300 {
		return "", fmt.Errorf("post-deployment read replay status %d: %s", status, truncate(string(payload), 1000))
	}
	var response struct {
		RunID    string `json:"runId"`
		IssueKey string `json:"issueKey"`
		Mode     string `json:"mode"`
	}
	if err := json.Unmarshal(payload, &response); err != nil {
		return "", fmt.Errorf("decode post-deployment read replay: %w", err)
	}
	if response.RunID == "" || response.IssueKey != issueKey || response.Mode != "read" {
		return "", errors.New("post-deployment read replay identity mismatch")
	}
	return response.RunID, nil
}

func validateSingleTicketReadPublication(payload []byte, status int, readRunID, issueKey string) (singleTicketPublicationVerification, error) {
	if status < 200 || status >= 300 {
		return singleTicketPublicationVerification{}, fmt.Errorf("post-deployment read publication status %d: %s", status, truncate(string(payload), 1000))
	}
	var response struct {
		RunID      string `json:"runId"`
		IssueKey   string `json:"issueKey"`
		Mode       string `json:"mode"`
		Evaluation struct {
			Status  string `json:"status"`
			Verdict string `json:"verdict"`
		} `json:"evaluation"`
		Publication struct {
			RunDBID    *int64   `json:"runDbId"`
			Database   string   `json:"database"`
			Jira       string   `json:"jira"`
			Evaluation string   `json:"evaluation"`
			Errors     []string `json:"errors"`
		} `json:"publication"`
		JiraInternalComment struct {
			Status     string  `json:"status"`
			CommentID  *string `json:"commentId"`
			CommentURL *string `json:"commentUrl"`
		} `json:"jiraInternalComment"`
	}
	if err := json.Unmarshal(payload, &response); err != nil {
		return singleTicketPublicationVerification{}, fmt.Errorf("decode post-deployment read publication: %w", err)
	}
	if response.RunID != readRunID || response.IssueKey != issueKey || response.Mode != "publish_read" || response.Publication.RunDBID == nil || response.Publication.Database != "written" ||
		(response.Publication.Jira != "written" && response.Publication.Jira != "updated") ||
		response.Publication.Evaluation != "written" ||
		(response.JiraInternalComment.Status != "written" && response.JiraInternalComment.Status != "updated") ||
		response.JiraInternalComment.CommentID == nil ||
		response.Evaluation.Status == "failed" || response.Evaluation.Verdict == "human_better" {
		return singleTicketPublicationVerification{}, fmt.Errorf("post-deployment read publication did not complete Jira/evaluation verification: %s", truncate(string(payload), 2000))
	}
	return singleTicketPublicationVerification{
		RunID:      response.RunID,
		RunDBID:    *response.Publication.RunDBID,
		CommentID:  *response.JiraInternalComment.CommentID,
		CommentURL: stringValue(response.JiraInternalComment.CommentURL),
	}, nil
}

func (r *CodexRunner) recordSingleTicketOptimizedVerified(
	ctx context.Context,
	job Job,
	repairPaths []string,
	verification singleTicketPublicationVerification,
	repairMergeSHA string,
) (string, string, error) {
	recordPaths := make([]string, 0, 1)
	for _, path := range repairPaths {
		clean := filepath.ToSlash(filepath.Clean(path))
		if strings.HasPrefix(clean, "auto-oncall-services/docs/opts/") && strings.HasSuffix(clean, ".md") {
			recordPaths = append(recordPaths, clean)
		}
	}
	if len(recordPaths) != 1 {
		return "", "", fmt.Errorf("verified quality repair must own exactly one docs/opts record, found %v", recordPaths)
	}
	baseSHA, err := r.fetchFreshMain(ctx)
	if err != nil {
		return "", "", fmt.Errorf("fetch main for optimization verification record: %w", err)
	}
	worktree := filepath.Join(r.config.WorkspaceRoot, job.ID+"-verification")
	branch := "auto-oncall/ticket-" + strings.ToLower(job.IssueKey) + "-verified-" + job.ID
	if err := r.git(ctx, r.config.RepoPath, "worktree", "add", "-b", branch, worktree, "origin/main"); err != nil {
		return "", "", fmt.Errorf("create optimization verification worktree: %w", err)
	}
	if err := r.verifyWorktreeBase(ctx, worktree, baseSHA); err != nil {
		return "", "", err
	}
	prompt := fmt.Sprintf(`Update only %s after successful case-specific verification.
Read the applicable AGENTS.md and the record. Change the matching problem from candidate or optimized_unverified to optimized_verified, update its verified timestamp and verification evidence, and keep the human-readable status consistent. Do not change applicability, matchers, unrelated problems, product code, tests, or any other file.

Verification evidence:
- issue: %s
- repair merge SHA: %s
- post-change replay run: %s
- persisted run DB id: %d
- Jira internal comment id: %s
- Jira internal comment URL: %s

The replay ran only after the merged SHA was live. The authorized publish-read path reused that exact read run, updated or created the stable public=false internal comment, and persisted the same result and evaluation without another analysis. Return a concise summary.`,
		recordPaths[0], job.IssueKey, repairMergeSHA, verification.RunID, verification.RunDBID,
		verification.CommentID, verification.CommentURL)
	message, _, err := r.runCodex(ctx, job, worktree, prompt, true, nil, "verification-record")
	if err != nil {
		return "", "", err
	}
	paths, err := changedPaths(ctx, worktree)
	if err != nil {
		return "", "", err
	}
	if len(paths) != 1 || paths[0] != recordPaths[0] {
		return "", "", fmt.Errorf("optimization verification may change only %s, changed %v", recordPaths[0], paths)
	}
	if err := r.validateSingleTicketCandidate(ctx, worktree); err != nil {
		return "", "", fmt.Errorf("validate optimization verification record: %w", err)
	}
	if err := r.git(ctx, worktree, "add", "--", recordPaths[0]); err != nil {
		return "", "", err
	}
	if err := r.git(ctx, worktree, "-c", "user.name=Auto Oncall Optimizer", "-c", "user.email=auto-oncall-optimizer@pingcap.com",
		"commit", "-m", "docs(auto-oncall): verify "+strings.ToLower(job.IssueKey)+" optimization"); err != nil {
		return "", "", fmt.Errorf("commit optimization verification record: %w", err)
	}
	if err := r.git(ctx, worktree, "push", "-u", "origin", branch); err != nil {
		return "", "", fmt.Errorf("push optimization verification record: %w", err)
	}
	prURL, err := r.command(ctx, worktree, r.config.GitHubBin, "pr", "create", "--repo", r.config.GitHubRepo,
		"--base", "main", "--head", branch, "--title", "docs(auto-oncall): verify "+strings.ToLower(job.IssueKey)+" optimization",
		"--body", fmt.Sprintf("Single-ticket job `%s` verified replay `%s` after repair `%s`.\n\n%s", job.ID, verification.RunID, repairMergeSHA, truncate(message, 5000)))
	if err != nil {
		return "", "", fmt.Errorf("create optimization verification pull request: %w", err)
	}
	prURL = strings.TrimSpace(prURL)
	mergeSHA, err := r.mergeAndDeploySingleTicket(ctx, worktree, prURL)
	if err != nil {
		return prURL, "", err
	}
	if err := r.removeWorktree(ctx, worktree, branch); err != nil {
		return prURL, mergeSHA, err
	}
	return prURL, mergeSHA, nil
}

func waitContext(ctx context.Context, duration time.Duration) error {
	timer := time.NewTimer(duration)
	defer timer.Stop()
	select {
	case <-ctx.Done():
		return ctx.Err()
	case <-timer.C:
		return nil
	}
}
