// Copyright 2016 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 github implements sync mechanism to mirror GitHub issue state
// into a [storage.DB] as well as code to inspect that state and to make
// issue changes on GitHub.
// All the functionality is provided by the [Client], created by [New].
package github

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"iter"
	"log/slog"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"

	"golang.org/x/oscar/internal/secret"
	"golang.org/x/oscar/internal/storage"
	"golang.org/x/oscar/internal/storage/timed"
	"rsc.io/ordered"
)

const (
	eventKind       = "github.Event"
	syncProjectKind = "github.SyncProject"
)

// This package stores the following key schemas in the database:
//
//	["github.SyncProject", Project] => JSON of projectSync structure
//	["github.Event", Project, Issue, API, ID] => [DBTime, Raw(JSON)]
//	["github.EventByTime", DBTime, Project, Issue, API, ID] => []
//
// To reconstruct the history of a given issue, scan for keys from
// ["github.Event", Project, Issue] to ["github.Event", Project, Issue, ordered.Inf].
//
// The API field is "/issues", "/issues/comments", or "/issues/events",
// so the first key-value pair is the issue creation event with the issue body text.
//
// The IDs are GitHub's and appear to be ordered by time within an API,
// so that the comments are time-ordered and the events are time-ordered,
// but comments and events are not ordered with respect to each other.
// To order them fully, fetch all the events and sort by the time in the JSON.
//
// The JSON is the raw JSON served from GitHub describing the event.
// Storing the raw JSON avoids having to re-download everything if we decide
// another field is of interest to us.
//
// EventByTime is an index of Events by DBTime, which is the time when the
// record was added to the database. Code that processes new events can
// record which DBTime it has most recently processed and then scan forward in
// the index to learn about new events.

// o is short for ordered.Encode.
func o(list ...any) []byte { return ordered.Encode(list...) }

// Scrub is a scrubber for use with [rsc.io/httprr] when writing
// tests that access GitHub through an httprr.RecordReplay.
// It removes auth credentials from the request.
func Scrub(req *http.Request) error {
	req.Header.Del("Authorization")
	return nil
}

// A Client is a connection to GitHub state in a database and on GitHub itself.
type Client struct {
	slog   *slog.Logger
	db     storage.DB
	secret secret.DB
	http   *http.Client

	testing bool

	testMu     sync.Mutex
	testClient *TestingClient
	testEdits  []*TestingEdit
	testEvents map[string]json.RawMessage
}

// New returns a new client that uses the given logger, databases, and HTTP client.
//
// The secret database is expected to have a secret named "api.github.com" of the
// form "user:pass" where user is a user-name (ignored by GitHub) and pass is an API token
// ("ghp_...").
func New(lg *slog.Logger, db storage.DB, sdb secret.DB, hc *http.Client) *Client {
	return &Client{
		slog:    lg,
		db:      db,
		secret:  sdb,
		http:    hc,
		testing: testing.Testing(),
	}
}

// A projectSync is per-GitHub project ("owner/repo") sync state stored in the database.
type projectSync struct {
	Name        string // owner/repo
	EventETag   string
	EventID     int64
	IssueDate   string
	CommentDate string
	RefillID    int64

	FullSyncActive bool
	FullSyncIssue  int64
}

// store stores proj into db.
func (proj *projectSync) store(db storage.DB) {
	db.Set(o(syncProjectKind, proj.Name), storage.JSON(proj))
}

// Add adds a GitHub project of the form
// "owner/repo" (for example "golang/go")
// to the database.
// It only adds the project sync metadata.
// The initial data fetch does not happen until [Sync] or [SyncProject] is called.
// If the project is already present, Add does nothing and returns nil.
func (c *Client) Add(project string) error {
	key := o(syncProjectKind, project)
	if _, ok := c.db.Get(key); ok {
		return nil
	}
	c.db.Set(key, storage.JSON(&projectSync{Name: project}))
	return nil
}

// Sync syncs all projects.
func (c *Client) Sync(ctx context.Context) error {
	for key := range c.db.Scan(o(syncProjectKind), o(syncProjectKind, ordered.Inf)) {
		var project string
		if err := ordered.Decode(key, nil, &project); err != nil {
			return fmt.Errorf("github client sync decode: key=%s err=%w", storage.Fmt(key), err)
		}
		if err := c.SyncProject(ctx, project); err != nil {
			c.slog.Error("github sync error", "project", project, "err", err)
		}
	}
	return nil
}

// If testFullSyncStop is non-nil, then SyncProject returns this error
// after each event is processed, to allow testing that interrupted syncs
// save state and can make progress.
var testFullSyncStop error

// SyncProject syncs a single project.
func (c *Client) SyncProject(ctx context.Context, project string) (err error) {
	c.slog.Debug("github.SyncProject", "project", project)
	defer func() {
		if err != nil {
			err = fmt.Errorf("SyncProject(%q): %w", project, err)
		}
	}()

	key := o(syncProjectKind, project)
	skey := string(key)

	// Lock the project, so that no one else is sync'ing
	// the project at the same time.
	c.db.Lock(skey)
	defer c.db.Unlock(skey)

	// Load sync state.
	var proj projectSync
	if val, ok := c.db.Get(key); !ok {
		return fmt.Errorf("missing project %v", project)
	} else if err := json.Unmarshal(val, &proj); err != nil {
		return err
	}

	// Sync issues, comments, events.
	if err := c.syncIssues(ctx, &proj); err != nil {
		return err
	}
	if err := c.syncIssueComments(ctx, &proj); err != nil {
		return err
	}

	// See syncIssueEvents doc comment for details about this dance.
	// The incremental event sync only works up to a certain number
	// of events. To initialize a repo, we need a “full sync” that scans one
	// issue at a time. We also need the full sync if we fall too far behind
	// by not syncing for many days.
	if proj.EventID == 0 || proj.FullSyncActive {
		// Full scan.
		if proj.EventID == 0 {
			proj.FullSyncActive = true
			proj.FullSyncIssue = 0
			proj.store(c.db)
			if err := c.syncIssueEvents(ctx, &proj, 0, true); err != nil {
				return err
			}
		}
		if err := c.syncIssues(ctx, &proj); err != nil {
			return err
		}
		for key := range c.db.Scan(o(eventKind, project), o(eventKind, project, ordered.Inf)) {
			var issue int64
			if _, err := ordered.DecodePrefix(key, nil, nil, &issue); err != nil {
				return err
			}
			if issue <= proj.FullSyncIssue {
				continue
			}
			if err := c.syncIssueEvents(ctx, &proj, issue, false); err != nil {
				return err
			}
			proj.FullSyncIssue = issue
			proj.store(c.db)
			if testFullSyncStop != nil {
				return testFullSyncStop
			}
		}
		// Fall through to incremental scan to clean up.
		proj.FullSyncActive = false
		proj.store(c.db)
	}

	// Incremental scan.
	if err := c.syncIssueEvents(ctx, &proj, 0, false); err != nil {
		return err
	}
	return nil
}

// syncIssues syncs the issues for a given project.
// It records all new issues since proj.IssueDate.
// If successful, it updates proj.IssueDate to the latest issue date seen.
func (c *Client) syncIssues(ctx context.Context, proj *projectSync) error {
	return c.syncByDate(ctx, proj, "/issues")
}

// syncIssueComments sync the issue comments for a given project.
// It records all new issue comments since proj.CommentDate.
// If successful, it updates proj.CommentDate to the latest comment date seen.
func (c *Client) syncIssueComments(ctx context.Context, proj *projectSync) error {
	return c.syncByDate(ctx, proj, "/issues/comments")
}

// syncByDate downloads and saves issues or issue comments since
// the date specified in proj (proj.IssueDate or proj.CommentDate).
// api is "/issues" for issues or "/issues/comments" for issue comments.
// syncByDate updates the proj date with the new latest date seen
// before any error.
func (c *Client) syncByDate(ctx context.Context, proj *projectSync, api string) error {
Restart:
	// For these APIs, we can ask GitHub for the event stream in increasing time order,
	// so we can iterate through all the events, saving the latest time we have seen,
	// and pick up where we left off.
	var since *string
	values := url.Values{
		"sort":      {"updated"},
		"direction": {"asc"},
		"page":      {"1"},
	}
	switch api {
	default:
		panic("downloadByDate api: " + api)
	case "/issues":
		since = &proj.IssueDate
		values["state"] = []string{"all"}
		values["per_page"] = []string{"100"}
	case "/issues/comments":
		since = &proj.CommentDate
	}
	if *since != "" {
		values["since"] = []string{*since}
	}

	b := c.db.Batch()
	defer b.Apply()

	urlStr := "https://api.github.com/repos/" + proj.Name + api + "?" + values.Encode()
	npage := 0
	defer proj.store(c.db)
	for pg, err := range c.pages(ctx, urlStr, "") {
		if err != nil {
			return err
		}

		for _, raw := range pg.body {
			var meta struct {
				ID        int64  `json:"id"`
				Updated   string `json:"updated_at"`
				Number    int64  `json:"number"`    // for /issues feed
				IssueURL  string `json:"issue_url"` // for /issues/comments feed
				CreatedAt string `json:"created_at"`
			}
			if err := json.Unmarshal(raw, &meta); err != nil {
				return fmt.Errorf("parsing JSON: %v", err)
			}
			if meta.ID == 0 {
				return fmt.Errorf("parsing message: no id: %s", string(raw))
			}
			if meta.Updated == "" {
				return fmt.Errorf("parsing JSON: no updated_at: %s", string(raw))
			}

			switch api {
			default:
				c.db.Panic("github downloadByDate bad api", "api", api)
			case "/issues":
				if meta.Number == 0 {
					return fmt.Errorf("parsing message: no number: %s", string(raw))
				}
			case "/issues/comments":
				n, err := strconv.ParseInt(meta.IssueURL[strings.LastIndex(meta.IssueURL, "/")+1:], 10, 64)
				if err != nil {
					return fmt.Errorf("invalid comment URL: %s", meta.IssueURL)
				}
				meta.Number = n
			}

			c.writeEvent(b, proj.Name, meta.Number, api, meta.ID, raw)
			b.MaybeApply()
			*since = meta.Updated
		}
		b.Apply()
		proj.store(c.db) // update *since

		// GitHub stops returning results after 1000 pages.
		// After 500 pages, restart pagination with a new since value.
		// TODO: Write a test.
		if npage++; npage >= 500 {
			goto Restart
		}
	}
	return nil
}

// syncIssueEvents downloads and saves new issue events in the given project.
//
// The /issues/events API does not have a "since time T" option:
// it lists events going backward in time, so we have to read backward
// until we find an event we've seen before. Only then can we update
// the "most recent seen event" proj.EventID, since otherwise there
// is still an unread gap between what we saw before and what we've
// seen so far. If syncIssueEvents is able to read back far enough, it
// updates proj.EventID and proj.EventETag.
//
// If onlySetLatest is true, syncIssueEvents does not store any events
// but does write down the most recent proj.EventID and proj.EventETag.
// (This doesn't make sense yet but keep reading.)
//
// The /issues/events API has a limit to how far back it can read,
// so if it has been a very long time since we last updated
// (or if this is the first sync), we may not reach the last known event.
// In that case, we have to resort to syncing each event separately
// using /issues/n/events, under the assumption that any one issue
// will be short enough to iterate its entire event list.
//
// If issue > 0, the sync uses /issues/n/events and does not update
// proj.EventID or proj.EventETag. The caller is expected to be looping
// over all events in this case.
//
// To sync all issues events in a repo with too many events, the full sync sequence is:
//
//   - c.syncIssueEvents(proj, 0, true) to set EventID and EventETag
//     to the current latest event in the repo, establishing a lower bound on what
//     we will record during the next steps.
//
//   - c.syncIssues(proj) to get the full list of issues.
//
//   - c.syncIssueEvents(proj, issue, false) for every issue found by syncIssues.
//
//     Now the database should contain all the events with id <= proj.EventID
//     but it may also contain newer ones.
//
//   - c.syncIssueEvents(proj, 0, false) to read any events since the beginning of the sync.
//
//     Now the database should contain all events up to the new proj.EventID.
func (c *Client) syncIssueEvents(ctx context.Context, proj *projectSync, issue int64, onlySetLatest bool) error {
	if issue > 0 && onlySetLatest {
		panic("syncIssueEvents misuse")
	}

	values := url.Values{
		"page":     {"1"},
		"per_page": {"100"},
	}
	var api = "/issues/events"
	if issue > 0 {
		api = fmt.Sprintf("/issues/%d/events", issue)
	}
	urlStr := "https://api.github.com/repos/" + proj.Name + api + "?" + values.Encode()

	var (
		firstID   int64
		firstETag string
		lastID    int64
		stopped   bool
	)

	b := c.db.Batch()
	defer b.Apply()

Pages:
	for pg, err := range c.pages(ctx, urlStr, proj.EventETag) {
		if err == errNotModified {
			return nil
		}
		if err != nil {
			return err
		}

		for _, raw := range pg.body {
			var meta struct {
				ID    int64  `json:"id"`
				URL   string `json:"url"`
				Issue struct {
					Number int64 `json:"number"`
				} `json:"issue"`
			}
			if err := json.Unmarshal(raw, &meta); err != nil {
				return fmt.Errorf("parsing JSON: %v", err)
			}
			if issue > 0 {
				meta.Issue.Number = issue
			} else if meta.Issue.Number == 0 {
				// Locking a GitHub comment thread on a *commit*
				// appears in the /issues/events stream. For example
				// https://github.com/golang/go/commit/af43932c20d5b59cdffca45406754dbccbb46dfa
				// is now locked and has this GitHub event in the /issues/events stream:
				//
				//	{
				//		"id": 13683643830,
				//		"node_id": "LOE_lADOAWBuf8DPAAAAAy-b1bY",
				//		"url": "https://api.github.com/repos/golang/go/issues/events/13683643830",
				//		"actor": {
				//			"login": "ianlancetaylor",
				//			...
				//		},
				//		"event": "locked",
				//		"commit_id": "af43932c20d5b59cdffca45406754dbccbb46dfa",
				//		"commit_url": "https://api.github.com/repos/golang/go/commits/af43932c20d5b59cdffca45406754dbccbb46dfa",
				//		"created_at": "2024-07-29T16:56:44Z",
				//		"lock_reason": null,
				//		"issue": null,
				//		"performed_via_github_app": null
				//	}
				//
				// Assume the lack of issue number is something like that.
				c.slog.Warn("github sync event without issue id", "json", raw)
				continue
			}
			if meta.ID == 0 {
				return fmt.Errorf("parsing message: no id: %s", string(raw))
			}
			if firstID == 0 {
				firstID = meta.ID
				firstETag = pg.resp.Header.Get("Etag")
			}
			lastID = meta.ID
			if issue == 0 && (onlySetLatest || proj.EventID != 0 && meta.ID <= proj.EventID) {
				stopped = true
				break Pages
			}

			c.writeEvent(b, proj.Name, meta.Issue.Number, "/issues/events", meta.ID, raw)
			b.MaybeApply()
		}
	}

	if issue == 0 && lastID != 0 && !stopped {
		return fmt.Errorf("lost sync: missing event IDs between %d and %d", proj.EventID, lastID)
	}

	if issue == 0 {
		proj.EventID = firstID
		proj.EventETag = firstETag
		proj.store(c.db)
	}
	return nil
}

// writeEvent writes a single event to the database using SetTimed, to maintain a time-ordered index.
func (c *Client) writeEvent(b storage.Batch, project string, issue int64, api string, id int64, raw json.RawMessage) {
	timed.Set(c.db, b, eventKind, o(project, issue, api, id), o(ordered.Raw(raw)))
}

// errNotModified is returned by get when an etag is being used
// and the server returns a 304 not modified response.
var errNotModified = errors.New("304 not modified")

// get fetches url and decodes the body as JSON into obj.
//
// If etag is non-empty, the request includes an If-None-Match: etag header
// and get returns errNotModified if the server says the object is unmodified
// since that etag.
//
// get uses the api.github.com secret if available.
// Otherwise it makes an unauthenticated request.
func (c *Client) get(ctx context.Context, url, etag string, obj any) (*http.Response, error) {
	if c.divertEdits() {
		c.testMu.Lock()
		js := c.testEvents[url]
		c.testMu.Unlock()
		if js != nil {
			resp := &http.Response{
				StatusCode: 200,
				Status:     "200 OK",
			}
			return resp, json.Unmarshal(js, obj)
		}
	}

	auth := Token(c.secret)
	nrate := 0
	nfail := 0
Redo:
	c.slog.Info("github get", "url", url)
	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", "Bearer "+auth)
	if etag != "" {
		req.Header.Set("If-None-Match", etag)
	}
	resp, err := c.http.Do(req)
	if err != nil {
		return nil, err
	}
	data, err := io.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return nil, fmt.Errorf("reading body: %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		if resp.StatusCode == http.StatusNotModified { // 304
			return nil, errNotModified
		}
		if c.rateLimit(resp) {
			if nrate++; nrate > 20 {
				return nil, fmt.Errorf("%s # too many rate limits\n%s", resp.Status, data)
			}
			goto Redo
		}
		if resp.StatusCode == http.StatusInternalServerError || resp.StatusCode == http.StatusBadGateway { // 500, 502
			c.slog.Error("github get server failure", "code", resp.StatusCode, "status", resp.Status, "body", string(data))
			if nfail++; nfail < 3 {
				time.Sleep(time.Duration(nfail) * 2 * time.Second)
				goto Redo
			}
		}
		return nil, fmt.Errorf("%s\n%s", resp.Status, data)
	}
	return resp, json.Unmarshal(data, obj)
}

// Token returns the secret for "api.github.com".
func Token(sdb secret.DB) string {
	auth, _ := sdb.Get("api.github.com")
	if _, pass, ok := strings.Cut(auth, ":"); ok {
		// Accept token as "password" in user:pass from netrc secret store
		return pass
	}
	return auth
}

// A page is an HTTP response with a body that is a JSON array of objects.
// The objects are not decoded (they are json.RawMessages).
type page struct {
	resp *http.Response
	body []json.RawMessage
}

// pages returns a paginated result starting at url and using etag.
// If pages encounters an error, it yields nil, err.
func (c *Client) pages(ctx context.Context, url, etag string) iter.Seq2[*page, error] {
	return func(yield func(*page, error) bool) {
		for url != "" {
			var body []json.RawMessage
			resp, err := c.get(ctx, url, etag, &body)
			if err != nil {
				yield(nil, err)
				return
			}
			if !yield(&page{resp, body}, nil) {
				return
			}
			url = findNext(resp.Header.Get("Link"))
		}
	}
}

// findNext finds the "next" URL in the Link header value.
// Sample Link header:
//
//	Link: <https://api.github.com/repositories/26468385/issues?direction=asc&page=2&per_page=100&sort=updated&state=all>; rel="next", <https://api.github.com/repositories/26468385/issues?direction=asc&page=2&per_page=100&sort=updated&state=all>; rel="last"
//
// The format is a comma-separated list of <LINK>; rel="type".
func findNext(link string) string {
	for link != "" {
		link = strings.TrimSpace(link)
		if !strings.HasPrefix(link, "<") {
			break
		}
		i := strings.Index(link, ">")
		if i < 0 {
			break
		}
		linkURL := link[1:i]
		link = strings.TrimSpace(link[i+1:])
		for strings.HasPrefix(link, ";") {
			link = strings.TrimSpace(link[1:])
			i := strings.Index(link, ";")
			j := strings.Index(link, ",")
			if i < 0 || j >= 0 && j < i {
				i = j
			}
			if i < 0 {
				i = len(link)
			}
			attr := strings.TrimSpace(link[:i])
			if attr == `rel="next"` {
				return linkURL
			}
			link = link[i:]
		}
		if !strings.HasPrefix(link, ",") {
			break
		}
		link = strings.TrimSpace(link[1:])
	}
	return ""
}

// rateLimit looks at the response to decide whether a rate limit has been applied.
// If so, rateLimit sleeps until the time specified in the response, plus a bit extra.
// rateLimit reports whether this was a rate-limit response.
func (c *Client) rateLimit(resp *http.Response) bool {
	if resp.StatusCode != http.StatusForbidden || resp.Header.Get("X-Ratelimit-Remaining") != "0" {
		return false
	}
	n, _ := strconv.Atoi(resp.Header.Get("X-Ratelimit-Reset"))
	if n == 0 {
		return false
	}
	t := time.Unix(int64(n), 0)
	now := time.Now()

	const timeSkew = 1 * time.Minute
	delay := t.Sub(now) + timeSkew
	if delay < 0 {
		// We are being asked to sleep until a time that already happened.
		// If it happened recently (within timeSkew), then maybe our clock
		// is just out of sync with GitHub's clock.
		// But if it happened long ago, we are probably reading an old HTTP trace.
		// In that case, return false (we didn't find a valid ratelimit).
		return false
	}
	c.slog.Info("github ratelimit", "reset", t.Format(time.RFC3339),
		"limit", resp.Header.Get("X-Ratelimit-Limit"),
		"remaining", resp.Header.Get("X-Ratelimit-Remaining"),
		"used", resp.Header.Get("X-Ratelimit-Used"))
	time.Sleep(delay)
	return true
}
