// Copyright 2025 The Go 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 main

import (
	"errors"
	"fmt"
	"net/http"
	"regexp"
	"sort"
	"strings"

	"golang.org/x/oscar/internal/bisect"
	"golang.org/x/oscar/internal/github"
)

// bisectLogPage is the data for the bisect log HTML template.
type bisectLogPage struct {
	CommonPage

	Tasks []*bisect.Task // all bisection tasks
}

var bisectLogPageTmpl = newTemplate(bisectLogTmplFile, nil)

func (g *Gaby) handleBisectLog(w http.ResponseWriter, r *http.Request) {
	var p bisectLogPage
	for _, t := range g.bisect.BisectionTasks() {
		p.Tasks = append(p.Tasks, t)
	}
	// Sort the tasks by creation time, from newest to oldest.
	sort.SliceStable(p.Tasks, func(i, j int) bool {
		return p.Tasks[i].Created.After(p.Tasks[j].Created)
	})
	p.setCommonPage()

	b, err := Exec(bisectLogPageTmpl, &p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, _ = w.Write(b)
}

func (p *bisectLogPage) setCommonPage() {
	p.CommonPage = CommonPage{
		ID:          bisectlogID,
		Description: "Browse bisection tasks performed by Oscar.",
		Form: Form{
			Inputs:     nil,
			SubmitText: "void",
		},
	}
}

// parseBisectTrigger extracts a bisection Request, if any,
// from a GitHub issue comment trigger. The expected request
// format for the comment body is as follows:
//
//   - there can be empty lines
//   - the first non-empty line is "@gabyhelp bisect [bad] [good]".
//     Both bad and good are optional, but if one is present so must
//     be the other.
//   - the regression body comes after and it is enclosed with
//     triple backticks (```).
//
// An error is returned if the trigger contains a bisect directive
// but the rest of the comment is not properly formatted.
func parseBisectTrigger(trigger *github.WebhookIssueCommentEvent) (*bisect.Request, error) {
	body := trigger.Comment.Body

	// Find the bisection directive line, if any.
	lines := strings.Split(body, "\n")
	i, bad, good, err := bisectDirectiveLine(lines)
	if err != nil {
		return nil, err
	}
	if i == -1 {
		return nil, nil
	}
	// If bad and good commits are not provided,
	// set them to default values.
	if bad == "" {
		bad = "master"
	}
	if good == "" {
		good = "go1.22.0"
	}

	// Extract the regression code from the rest
	// of the body.
	rest := strings.Join(lines[i+1:], "\n")
	regression := strings.TrimSpace(bisectRegression(rest))
	if regression == "" {
		return nil, errors.New("missing bisect regression")
	}
	return &bisect.Request{
		Trigger: trigger.Comment.URL,
		Issue:   trigger.Issue.URL,
		Repo:    "https://go.googlesource.com/go",
		Fail:    bad,
		Pass:    good,
		Body:    regression,
	}, nil
}

// bisectDirectiveLine checks if there is a line
// encoding a bisection directive. If so, it
// returns the position of the line and it extracts
// the bisect commits from the line. If the line
// is not properly formatted, returns an error.
func bisectDirectiveLine(lines []string) (int, string, string, error) {
	for i, l := range lines {
		l = strings.TrimSpace(l)
		fs := strings.Fields(l)
		if len(fs) < 2 {
			continue
		}
		if fs[0] != "@gabyhelp" || fs[1] != "bisect" {
			continue
		}
		// Bisect directive identified, check for
		// commits and errors.
		if len(fs) == 2 {
			// Only bisect directive is present.
			return i, "", "", nil
		}
		if len(fs) == 4 {
			// Both the bisect directive and
			// two commits are present.
			return i, fs[2], fs[3], nil
		}
		return i, "", "", fmt.Errorf("bisect directive not properly formatted: %s", l)

	}
	return -1, "", "", nil
}

// regressionRegexp matches any text, including
// newlines, that is surrounded by triple backticks.
var regressionRegexp = regexp.MustCompile("(?s)```(.+)```")

// bisectRegression extracts a regression test
// case from body.
func bisectRegression(body string) string {
	matches := regressionRegexp.FindAllStringSubmatch(body, -1)
	if len(matches) != 1 {
		return ""
	}
	rmatches := matches[0]
	if len(rmatches) != 2 {
		return ""
	}
	return rmatches[1]
}
