// Copyright 2024 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.

//go:build go1.21

package main

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"io/fs"
	"strings"
	"time"

	"golang.org/x/build/gerrit"
	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
)

type ToDo struct {
	message    string // what is to be done
	provenance string // where the TODO came from
}

// todo prints a report to w on which release notes need to be written.
// It takes the doc/next directory of the repo and the date of the last release.
func todo(w io.Writer, fsys fs.FS, prevRelDate time.Time) error {
	var todos []ToDo

	add := func(td ToDo) { todos = append(todos, td) }

	if err := todosFromDocFiles(fsys, add); err != nil {
		return err
	}
	if !prevRelDate.IsZero() {
		if err := todosFromRelnoteCLs(prevRelDate, add); err != nil {
			return err
		}
	}
	return writeToDos(w, todos)
}

// Collect TODOs from the markdown files in the main repo.
func todosFromDocFiles(fsys fs.FS, add func(ToDo)) error {
	// This is essentially a grep.
	return fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if !d.IsDir() && strings.HasSuffix(path, ".md") {
			if err := todosFromFile(fsys, path, add); err != nil {
				return err
			}
		}
		return nil
	})
}

func todosFromFile(dir fs.FS, filename string, add func(ToDo)) error {
	f, err := dir.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()
	scan := bufio.NewScanner(f)
	ln := 0
	for scan.Scan() {
		ln++
		if line := scan.Text(); strings.Contains(line, "TODO") {
			add(ToDo{
				message:    line,
				provenance: fmt.Sprintf("%s:%d", filename, ln),
			})
		}
	}
	return scan.Err()
}

func todosFromRelnoteCLs(cutoff time.Time, add func(ToDo)) error {
	ctx := context.Background()
	// The maintner corpus doesn't track inline comments. See go.dev/issue/24863.
	// So we need to use a Gerrit API client to fetch them instead. If maintner starts
	// tracking inline comments in the future, this extra complexity can be dropped.
	gerritClient := gerrit.NewClient("https://go-review.googlesource.com", gerrit.NoAuth)
	matchedCLs, err := findCLsWithRelNote(gerritClient, cutoff)
	if err != nil {
		return err
	}
	corpus, err := godata.Get(ctx)
	if err != nil {
		return err
	}
	return corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Status != "merged" {
				return nil
			}
			if cl.Branch() != "master" {
				// Ignore CLs sent to development or release branches.
				return nil
			}
			if cl.Commit.CommitTime.Before(cutoff) {
				// Was in a previous release; not for this one.
				return nil
			}
			// TODO(jba): look for accepted proposals that don't have release notes.
			if _, ok := matchedCLs[int(cl.Number)]; ok {
				comments, err := gerritClient.ListChangeComments(context.Background(), fmt.Sprint(cl.Number))
				if err != nil {
					return err
				}
				if rn := clRelNote(cl, comments); rn != "" {
					if rn == "yes" || rn == "y" {
						rn = "UNKNOWN"
					}
					add(ToDo{
						message:    "TODO:" + rn,
						provenance: fmt.Sprintf("RELNOTE comment in https://go.dev/cl/%d", cl.Number),
					})
				}
			}
			return nil
		})
	})
}

func writeToDos(w io.Writer, todos []ToDo) error {
	for _, td := range todos {
		if _, err := fmt.Fprintf(w, "%s (from %s)\n", td.message, td.provenance); err != nil {
			return err
		}
	}
	return nil
}
