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

package main

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"slices"

	"golang.org/x/oscar/internal/actions"
	"golang.org/x/oscar/internal/docs"
	"golang.org/x/oscar/internal/github"
)

// handleGitHubEvent handles incoming webhook requests from GitHub
// and reports whether the request was handled.
//
// If the incoming request was triggered by supported event, and sync
// is enabled, it syncs its relevant state. If changes are enabled,
// it takes relevant actions in response to the event.
//
// Otherwise, it logs the event and returns (false, nil).
//
// The supported events are:
//   - new GitHub issue (see [Gaby.handleGitHubIssueEvent])
//   - new GitHub issue comment (see [Gaby.handleGitHubIssueCommentEvent])
//
// handled is true if all appropriate syncs and actions were performed
// in response to the event, and false if the event was skipped or an
// error occurred. (handled is also false if either of [gabyFlags.enablesync]
// or [gabyFlags.enablechanges] is false.)
//
// handleGitHubEvent returns an error if any of the syncs or actions fails,
// or if the webhook request is invalid according to [github.ValidateWebhookRequest].
func (g *Gaby) handleGitHubEvent(r *http.Request, fl *gabyFlags) (handled bool, err error) {
	event, err := github.ValidateWebhookRequest(r, g.secret)
	if err != nil {
		return false, fmt.Errorf("%w: %v", errInvalidWebhookRequest, err)
	}

	if !slices.Contains(g.githubProjects, event.Project()) {
		g.slog.Warn("unexpected webhook request", "webhook_project", event.Project(), "gaby_project", g.githubProjects, "event", event)
		return false, nil
	}

	switch p := event.Payload.(type) {
	case *github.WebhookIssueEvent:
		return g.handleGitHubIssueEvent(r.Context(), p, fl)
	case *github.WebhookIssueCommentEvent:
		return g.handleGitHubIssueCommentEvent(r.Context(), p, fl)
	default:
		g.slog.Info("ignoring GitHub event", "type", event.Type, "event", event)
	}

	return false, nil
}

var errInvalidWebhookRequest = errors.New("invalid webhook request")

// handleGitHubIssueEvent handles an incoming GitHub "issue" event and
// reports whether the event was handled.
//
// If the event is a new issue, and sync is enabled, the function
// syncs the corresponding GitHub project. If changes are also enabled,
// it posts related issues and fixes the body and comments of the issue.
//
// It returns an error immediately if any of the syncs or actions fails.
//
// Otherwise, it logs the event and returns (false, nil).
func (g *Gaby) handleGitHubIssueEvent(ctx context.Context, event *github.WebhookIssueEvent, fl *gabyFlags) (handled bool, _ error) {
	if event.Action != github.WebhookIssueActionOpened {
		g.slog.Info("ignoring GitHub issue event (action is not opened)", "event", event, "action", event.Action)
		return false, nil
	}

	g.slog.Info("handling GitHub issue", "event", event)

	project := event.Repository.Project
	if fl.enablesync {
		if err := g.syncGitHubProject(ctx, project); err != nil {
			return false, err
		}
		if err := g.embedAll(ctx); err != nil {
			return false, err
		}
	}

	// Do not attempt changes unless sync is enabled and completely succeeded.
	if fl.enablechanges && fl.enablesync {
		// No need to lock; [related.Poster.Post] and [related.Poster.Run] can
		// happen concurrently.
		if err := g.relatedPoster.Post(ctx, project, event.Issue.Number); err != nil {
			return false, err
		}
		if err := g.fixGitHubIssue(ctx, project, event.Issue.Number); err != nil {
			return false, err
		}
		return true, nil
	}

	return false, nil
}

// handleGitHubIssueCommentEvent handles an incoming GitHub "issue comment" event
// and reports whether the event was handled.
//
// If the event is a new issue comment, and sync is enabled, the function
// syncs the corresponding GitHub project. If changes are also enabled,
// it fixes the body and comments of the issue to which the comment
// was posted.
//
// It returns an error immediately if any of the syncs or actions fails.
//
// Otherwise, it logs the event and returns (false, nil).
func (g *Gaby) handleGitHubIssueCommentEvent(ctx context.Context, event *github.WebhookIssueCommentEvent, fl *gabyFlags) (handled bool, _ error) {
	if event.Action != github.WebhookIssueCommentActionCreated {
		g.slog.Info("ignoring GitHub issue comment event (action is not created)", "event", event, "action", event.Action)
		return false, nil
	}

	g.slog.Info("handling GitHub issue comment", "event", event)

	project := event.Repository.Project
	if fl.enablesync {
		if err := g.syncGitHubProject(ctx, project); err != nil {
			return false, err
		}
		// Embeddings are not needed to apply fixes.
	}

	// Do not attempt changes unless sync is enabled and completely succeeded.
	if fl.enablechanges && fl.enablesync {
		if err := g.fixGitHubIssue(ctx, project, event.Issue.Number); err != nil {
			return false, err
		}
		return true, nil
	}

	return false, nil
}

func (g *Gaby) fixGitHubIssue(ctx context.Context, project string, issue int64) error {
	// No need to lock; [commentfix.Fixer.FixGitHubIssue] and
	// [commentfix.Fixer.Run] can happen concurrently.
	if err := g.commentFixer.LogFixGitHubIssue(ctx, project, issue); err != nil {
		return err
	}
	if err := actions.Run(ctx, g.slog, g.db); err != nil {
		return err
	}
	return nil
}

// syncGitHubProject syncs the document corpus with respect to a single
// GitHub project.
func (g *Gaby) syncGitHubProject(ctx context.Context, project string) error {
	g.db.Lock(gabyGitHubSyncLock)
	defer g.db.Unlock(gabyGitHubSyncLock)

	if err := g.github.SyncProject(ctx, project); err != nil {
		return err
	}
	docs.Sync(g.docs, g.github)
	return nil
}
