// Copyright 2019 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 sendwikidiff implements a Google Cloud background function that
// reacts to a pubsub message containing a GitHub webhook change payload.
// It assumes the payload is in reaction to a change to the Go wiki, then
// sends the full diff to the golang-wikichanges mailing list.
package sendwikidiff

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"html/template"
	"net/url"
	"os"
	"os/exec"
	"path"
	"sync"

	"github.com/sendgrid/sendgrid-go"
	"github.com/sendgrid/sendgrid-go/helpers/mail"
)

const repoURL = "https://github.com/golang/go.wiki.git"

var sendgridAPIKey = os.Getenv("SENDGRID_API_KEY")

type pubsubMessage struct {
	Data []byte `json:"data"`
}

func HandleWikiChangePubSub(ctx context.Context, m pubsubMessage) error {
	if sendgridAPIKey == "" {
		return fmt.Errorf("Environment variable SENDGRID_API_KEY is empty")
	}

	var payload struct {
		Pages []struct {
			PageName string `json:"page_name"`
			SHA      string `json:"sha"`
		} `json:"pages"`
	}
	if err := json.Unmarshal(m.Data, &payload); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to decode payload: %v", err)
		return err
	}

	repo := newGitRepo(repoURL, tempRepoDir(repoURL))
	if err := repo.update(); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to update repo: %v", err)
		return err
	}
	for _, page := range payload.Pages {
		out, err := repo.cmdShow(page.SHA).Output()
		if err != nil {
			fmt.Fprintf(os.Stderr, "Could not show SHA %q: %v", page.SHA, err)
			return err
		}
		if err := sendEmail(page.PageName, string(out)); err != nil {
			fmt.Fprintf(os.Stderr, "Could not send email: %v", err)
			return err
		}
	}
	return nil
}

func tempRepoDir(repoURL string) string {
	return path.Join(os.TempDir(), url.PathEscape(repoURL))
}

var htmlTmpl = template.Must(template.New("email").Parse(`<p><a href="{{.PageURL}}">View page</a></p>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;">{{.Diff}}</pre>
`))

func emailBody(page, diff string) (string, error) {
	var buf bytes.Buffer
	if err := htmlTmpl.Execute(&buf, struct {
		PageURL, Diff string
	}{
		Diff:    diff,
		PageURL: fmt.Sprintf("https://golang.org/wiki/%s", page),
	}); err != nil {
		return "", fmt.Errorf("template.Execute: %v", err)
	}
	return buf.String(), nil
}

func sendEmailSendGrid(page, diff string) error {
	from := mail.NewEmail("WikiDiffBot", "nobody@golang.org")
	subject := fmt.Sprintf("golang.org/wiki/%s was updated", page)
	to := mail.NewEmail("", "golang-wikichanges@googlegroups.com")

	body, err := emailBody(page, diff)
	if err != nil {
		return fmt.Errorf("emailBody: %v", err)
	}
	message := mail.NewSingleEmail(from, subject, to, diff, body)
	client := sendgrid.NewSendClient(sendgridAPIKey)
	_, err = client.Send(message)
	return err
}

// sendEmail sends an email that the golang.org/wiki/$page was updated
// with the provided diff.
// Var for testing.
var sendEmail func(page, diff string) error = sendEmailSendGrid

type gitRepo struct {
	sync.RWMutex

	repo string // remote address of repo
	dir  string // location of the repo
}

func newGitRepo(repo, dir string) *gitRepo {
	return &gitRepo{
		repo: repo,
		dir:  dir,
	}
}

func (r *gitRepo) clone() error {
	r.Lock()
	defer r.Unlock()
	cmd := exec.Command("git", "clone", r.repo, r.dir)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil
}

func (r *gitRepo) pull() error {
	r.Lock()
	defer r.Unlock()
	cmd := exec.Command("git", "pull")
	cmd.Dir = r.dir
	cmd.Env = append(os.Environ(), "PWD="+r.dir)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil
}

func (r *gitRepo) update() error {
	r.RLock()
	_, err := os.Stat(r.dir)
	r.RUnlock()
	if os.IsNotExist(err) {
		if err := r.clone(); err != nil {
			return fmt.Errorf("could not clone %q into %q: %v", r.repo, r.dir, err)
		}
		return nil
	}

	if err := r.pull(); err != nil {
		return fmt.Errorf("could not pull %q: %v", r.repo, err)
	}
	return nil
}

func (r *gitRepo) cmdShow(ref string) *exec.Cmd {
	r.RLock()
	defer r.RUnlock()
	cmd := exec.Command("git", "show", ref)
	cmd.Dir = r.dir
	cmd.Env = append(os.Environ(), "PWD="+r.dir)
	return cmd
}
