// Copyright 2021 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 task

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"io"
	"math"
	"math/rand"
	"mime/multipart"
	"net/http"
	"strings"
	"text/template"
	"time"

	"github.com/McKael/madon/v3"
	"github.com/dghubble/oauth1"
	"github.com/esimov/stackblur-go"
	"golang.org/x/build/internal/secret"
	"golang.org/x/build/internal/workflow"
	"golang.org/x/build/maintner/maintnerd/maintapi/version"
	"golang.org/x/image/font"
	"golang.org/x/image/font/gofont/gomono"
	"golang.org/x/image/font/opentype"
	"golang.org/x/image/math/fixed"
)

// releaseTweet describes a tweet that announces a Go release.
type releaseTweet struct {
	// Kind is the kind of release being announced.
	Kind ReleaseKind

	// Version is the Go version that has been released.
	//
	// The version string must use the same format as Go tags. For example:
	//   - "go1.21rc2" for a pre-release
	//   - "go1.21.0" for a major Go release
	//   - "go1.21.1" for a minor Go release
	Version string
	// SecondaryVersion is an older Go version that was also released.
	// This only applies to minor releases when two releases are made.
	// For example, "go1.20.9".
	SecondaryVersion string

	// Security is an optional sentence describing security fixes
	// included in this release.
	//
	// The empty string means there are no security fixes to highlight.
	// Past examples:
	//   - "Includes a security fix for the Wasm port (CVE-2021-38297)."
	//   - "Includes a security fix for archive/zip (CVE-2021-39293)."
	//   - "Includes a security fix for crypto/tls (CVE-2021-34558)."
	//   - "Includes security fixes for archive/zip, net, net/http/httputil, and math/big packages."
	Security string

	// Announcement is the announcement URL.
	//
	// It's applicable to all release types other than major,
	// since major releases point to release notes instead.
	// For example, "https://groups.google.com/g/golang-announce/c/wB1fph5RpsE/m/ZGwOsStwAwAJ".
	Announcement string
}

type Poster interface {
	// PostTweet posts a tweet with the given text and PNG image,
	// both of which must be non-empty, and returns the tweet URL.
	//
	// ErrTweetTooLong error is returned if posting fails
	// due to the tweet text length exceeding Twitter's limit.
	PostTweet(text string, imagePNG []byte, altText string) (tweetURL string, _ error)
}

// SocialMediaTasks contains tasks related to the release tweet.
type SocialMediaTasks struct {
	// TwitterClient can be used to post a tweet.
	TwitterClient  Poster
	MastodonClient Poster

	// RandomSeed is the pseudo-random number generator seed to use for presentational
	// choices, such as selecting one out of many available emoji or release archives.
	// The zero value means to use time.Now().UnixNano().
	RandomSeed int64
}

func (t SocialMediaTasks) textAndImage(ctx *workflow.TaskContext, kind ReleaseKind, published []Published, security string, announcement string) (tweetText string, imagePNG []byte, imageText string, err error) {
	if len(published) < 1 || len(published) > 2 {
		return "", nil, "", fmt.Errorf("got %d published Go releases, TweetRelease supports only 1 or 2 at once", len(published))
	}

	r := releaseTweet{
		Kind:         kind,
		Version:      published[0].Version,
		Security:     security,
		Announcement: announcement,
	}
	if len(published) == 2 {
		r.SecondaryVersion = published[1].Version
	}

	seed := t.RandomSeed
	if seed == 0 {
		seed = time.Now().UnixNano()
	}
	rnd := rand.New(rand.NewSource(seed))

	// Generate tweet text.
	tweetText, err = r.tweetText(rnd)
	if err != nil {
		return "", nil, "", err
	}
	ctx.Printf("tweet text:\n%s\n", tweetText)

	// Generate tweet image.
	imagePNG, imageText, err = tweetImage(published[0], rnd)
	if err != nil {
		return "", nil, "", err
	}
	ctx.Printf("tweet image:\n%s\n", imageText)
	return tweetText, imagePNG, imageText, nil
}

// TweetRelease posts a tweet announcing that a Go release has been published.
// ErrTweetTooLong is returned if the inputs result in a tweet that's too long.
func (t SocialMediaTasks) TweetRelease(ctx *workflow.TaskContext, kind ReleaseKind, published []Published, security string, announcement string) (_ string, _ error) {
	tweetText, imagePNG, imageText, err := t.textAndImage(ctx, kind, published, security, announcement)
	if err != nil {
		return "", err
	}

	// Post a tweet via the Twitter API.
	if t.TwitterClient == nil {
		return "(dry-run)", nil
	}
	ctx.DisableRetries()
	return t.TwitterClient.PostTweet(tweetText, imagePNG, imageText)
}

// TrumpetRelease posts a tweet announcing that a Go release has been published.
func (t SocialMediaTasks) TrumpetRelease(ctx *workflow.TaskContext, kind ReleaseKind, published []Published, security string, announcement string) (_ string, _ error) {
	tweetText, imagePNG, imageText, err := t.textAndImage(ctx, kind, published, security, announcement)
	if err != nil {
		return "", err
	}

	// Post via the Mastodon API.
	if t.MastodonClient == nil {
		return "(dry-run)", nil
	}
	ctx.DisableRetries()
	return t.MastodonClient.PostTweet(tweetText, imagePNG, imageText)
}

// tweetText generates the text to use in the announcement
// tweet for release r.
func (r *releaseTweet) tweetText(rnd *rand.Rand) (string, error) {
	// Parse the tweet text template
	// using rnd for emoji selection.
	t, err := template.New("").Funcs(template.FuncMap{
		"emoji": func(category string) (string, error) {
			es, ok := emoji[category]
			if !ok {
				return "", fmt.Errorf("unknown emoji category %q", category)
			}
			return es[rnd.Intn(len(es))], nil
		},

		// short and helpers below manipulate valid Go version strings
		// for the current needs of the tweet templates.
		"short": func(v string) string { return strings.TrimPrefix(v, "go") },
		// major extracts the major prefix of a valid Go version.
		// For example, major("go1.18.4") == "1.18".
		"major": func(v string) (string, error) {
			x, ok := version.Go1PointX(v)
			if !ok {
				return "", fmt.Errorf("internal error: version.Go1PointX(%q) is not ok", v)
			}
			return fmt.Sprintf("1.%d", x), nil
		},
		// build extracts the pre-release build number of a valid Go version.
		// For example, build("go1.19beta2") == "2".
		"build": func(v string) (string, error) {
			if i := strings.Index(v, "beta"); i != -1 {
				return v[i+len("beta"):], nil
			} else if i := strings.Index(v, "rc"); i != -1 {
				return v[i+len("rc"):], nil
			}
			return "", fmt.Errorf("internal error: unhandled pre-release Go version %q", v)
		},
	}).Parse(tweetTextTmpl)
	if err != nil {
		return "", err
	}

	// Select the appropriate template name.
	var name string
	switch r.Kind {
	case KindBeta:
		name = "beta"
	case KindRC:
		name = "rc"
	case KindMajor:
		name = "major"
	case KindMinor:
		name = "minor"
	default:
		return "", fmt.Errorf("unknown release kind: %v", r.Kind)
	}
	if r.SecondaryVersion != "" && name != "minor" {
		return "", fmt.Errorf("tweet template %q doesn't support more than one release; the SecondaryVersion field can only be used in minor releases", name)
	}

	var buf bytes.Buffer
	if err := t.ExecuteTemplate(&buf, name, r); err != nil {
		return "", err
	}
	return buf.String(), nil
}

const tweetTextTmpl = `{{define "minor" -}}
{{emoji "release"}} Go {{.Version|short}} {{with .SecondaryVersion}}and {{.|short}} are{{else}}is{{end}} released!

{{with .Security}}{{emoji "security"}} Security: {{.}}{{"\n\n"}}{{end -}}

{{emoji "announce"}} Announcement: {{.Announcement}}

{{emoji "download"}} Download: https://go.dev/dl/#{{.Version}}

#golang{{end}}


{{define "beta" -}}
{{emoji "beta-release"}} Go {{.Version|major}} Beta {{.Version|build}} is released!

{{with .Security}}{{emoji "security"}} Security: {{.}}{{"\n\n"}}{{end -}}

{{emoji "try"}} Try it! File bugs! https://go.dev/issue/new

{{emoji "announce"}} Announcement: {{.Announcement}}

{{emoji "download"}} Download: https://go.dev/dl/#{{.Version}}

#golang{{end}}


{{define "rc" -}}
{{emoji "rc-release"}} Go {{.Version|major}} Release Candidate {{.Version|build}} is released!

{{with .Security}}{{emoji "security"}} Security: {{.}}{{"\n\n"}}{{end -}}

{{emoji "run"}} Run it in dev! Run it in prod! File bugs! https://go.dev/issue/new

{{emoji "announce"}} Announcement: {{.Announcement}}

{{emoji "download"}} Download: https://go.dev/dl/#{{.Version}}

#golang{{end}}


{{define "major" -}}
{{emoji "release"}} Go {{.Version|short}} is released!

{{with .Security}}{{emoji "security"}} Security: {{.}}{{"\n\n"}}{{end -}}

{{emoji "notes"}} Release notes: https://go.dev/doc/go{{.Version|major}}

{{emoji "download"}} Download: https://go.dev/dl/#{{.Version}}

#golang{{end}}`

// emoji is an atlas of emoji for different categories.
//
// The more often an emoji is included in a category,
// the more likely it is to be randomly chosen.
var emoji = map[string][]string{
	"release": {
		"🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳",
		"🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉",
		"🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊",
		"🌟", "🌟", "🌟", "🌟", "🌟", "🌟", "🌟", "🌟",
		"🎆", "🎆", "🎆", "🎆", "🎆", "🎆",
		"🆒",
		"🕶",
		"🤯",
		"🧨",
		"💃",
		"🐕",
		"👩🏽‍🔬",
		"🌞",
	},
	"beta-release": {
		"🧪", "🧪", "🧪", "🧪", "🧪", "🧪", "🧪", "🧪", "🧪", "🧪",
		"⚡️", "⚡️", "⚡️", "⚡️", "⚡️", "⚡️", "⚡️", "⚡️", "⚡️", "⚡️",
		"💥",
	},
	"rc-release": {
		"🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳", "🥳",
		"🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉", "🎉",
		"🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊", "🎊",
		"🌞",
	},
	"security": {
		"🔐", "🔐", "🔐", "🔐", "🔐",
		"🔏", "🔏",
		"🔒",
	},
	"try": {
		"⚙️",
	},
	"run": {
		"🏃‍♀️",
		"🏃‍♂️",
		"🏖",
	},
	"announce": {
		"🗣", "🗣", "🗣", "🗣", "🗣", "🗣",
		"📣", "📣", "📣", "📣", "📣", "📣",
		"📢", "📢", "📢", "📢", "📢", "📢",
		"🔈", "🔈", "🔈", "🔈", "🔈",
		"📡", "📡", "📡", "📡",
		"📰",
	},
	"notes": {
		"📝", "📝", "📝", "📝", "📝",
		"🗒️", "🗒️", "🗒️", "🗒️", "🗒️",
		"📰",
	},
	"download": {
		"⬇️", "⬇️", "⬇️", "⬇️", "⬇️", "⬇️", "⬇️", "⬇️", "⬇️",
		"📦", "📦", "📦", "📦", "📦", "📦", "📦", "📦", "📦",
		"🗃",
		"🚚",
	},
}

// tweetImage generates an image to use in the announcement
// tweet for published. It returns the image encoded as PNG,
// and the text displayed in the image.
//
// tweetImage selects a random release archive to highlight.
func tweetImage(published Published, rnd *rand.Rand) (imagePNG []byte, imageText string, _ error) {
	a, err := pickRandomArchive(published, rnd)
	if err != nil {
		return nil, "", err
	}
	var buf bytes.Buffer
	if err := goCmdTmpl.Execute(&buf, map[string]string{
		"GoVer":    published.Version,
		"GOOS":     a.OS,
		"GOARCH":   a.GOARCH(),
		"Filename": a.Filename,
		"ZeroSize": fmt.Sprintf("%*d", digits(a.Size), 0),
		"HalfSize": fmt.Sprintf("%*d", digits(a.Size), a.Size/2),
		"FullSize": fmt.Sprint(a.Size),
	}); err != nil {
		return nil, "", err
	}
	imageText = buf.String()
	m, err := drawTerminal(imageText)
	if err != nil {
		return nil, "", err
	}
	// Encode the image in PNG format.
	buf.Reset()
	err = (&png.Encoder{CompressionLevel: png.BestCompression}).Encode(&buf, m)
	if err != nil {
		return nil, "", err
	}
	return buf.Bytes(), imageText, nil
}

var goCmdTmpl = template.Must(template.New("").Parse(`$ go install golang.org/dl/{{.GoVer}}@latest
$ {{.GoVer}} download
Downloaded   0.0% ({{.ZeroSize}} / {{.FullSize}} bytes) ...
Downloaded  50.0% ({{.HalfSize}} / {{.FullSize}} bytes) ...
Downloaded 100.0% ({{.FullSize}} / {{.FullSize}} bytes)
Unpacking {{.Filename}} ...
Success. You may now run '{{.GoVer}}'
$ {{.GoVer}} version
go version {{.GoVer}} {{.GOOS}}/{{.GOARCH}}`))

// digits reports the number of digits in the integer i. i must be non-zero.
func digits(i int64) int {
	var n int
	for ; i != 0; i /= 10 {
		n++
	}
	return n
}

// pickRandomArchive picks one random release archive
// to showcase in an image showing sample output from
// 'go install golang.org/dl/...@latest'.
func pickRandomArchive(published Published, rnd *rand.Rand) (archive WebsiteFile, _ error) {
	var archives []WebsiteFile
	for _, f := range published.Files {
		if f.Kind != "archive" {
			// Not an archive type of file, skip. The golang.org/dl commands use archives only.
			continue
		}
		archives = append(archives, f)
	}
	if len(archives) == 0 {
		return WebsiteFile{}, fmt.Errorf("release version %q has 0 archive files", published.Version)
	}
	return archives[rnd.Intn(len(archives))], nil
}

// drawTerminal draws an image of a terminal window
// with the given text displayed.
func drawTerminal(text string) (image.Image, error) {
	// Load font from TTF data.
	f, err := opentype.Parse(gomono.TTF)
	if err != nil {
		return nil, err
	}

	// Keep image width within 900 px, so that Twitter doesn't convert it to a lossy JPEG.
	// See https://twittercommunity.com/t/upcoming-changes-to-png-image-support/118695.
	const width, height = 900, 520
	m := image.NewNRGBA(image.Rect(0, 0, width, height))

	// Background.
	draw.Draw(m, m.Bounds(), image.NewUniform(gopherBlue), image.Point{}, draw.Src)

	// Shadow.
	draw.DrawMask(m, m.Bounds(), image.NewUniform(shadowColor), image.Point{},
		roundedRect(image.Rect(50, 80, width-50, height-80).Add(image.Point{Y: 20}), 10), image.Point{}, draw.Over)

	// Blur.
	m, err = stackblur.Process(m, 80)
	if err != nil {
		return nil, err
	}

	// Terminal.
	draw.DrawMask(m, m.Bounds(), image.NewUniform(terminalColor), image.Point{},
		roundedRect(image.Rect(50, 80, width-50, height-80), 10), image.Point{}, draw.Over)

	// Text.
	face, err := opentype.NewFace(f, &opentype.FaceOptions{Size: 24, DPI: 72})
	if err != nil {
		return nil, err
	}
	d := font.Drawer{Dst: m, Src: image.White, Face: face}
	const lineHeight = 32
	for n, line := range strings.Split(text, "\n") {
		d.Dot = fixed.P(80, 135+n*lineHeight)
		d.DrawString(line)
	}

	return m, nil
}

// roundedRect returns a rounded rectangle with the specified border radius.
func roundedRect(r image.Rectangle, borderRadius int) image.Image {
	return roundedRectangle{
		r:  r,
		i:  r.Inset(borderRadius),
		br: borderRadius,
	}
}

type roundedRectangle struct {
	r  image.Rectangle // Outer bounds.
	i  image.Rectangle // Inner bounds, border radius away from outer.
	br int             // Border radius.
}

func (roundedRectangle) ColorModel() color.Model   { return color.Alpha16Model }
func (r roundedRectangle) Bounds() image.Rectangle { return r.r }
func (r roundedRectangle) At(x, y int) color.Color {
	switch {
	case x < r.i.Min.X && y < r.i.Min.Y:
		return circle(x-r.i.Min.X, y-r.i.Min.Y, r.br)
	case x > r.i.Max.X-1 && y < r.i.Min.Y:
		return circle(x-(r.i.Max.X-1), y-r.i.Min.Y, r.br)
	case x < r.i.Min.X && y > r.i.Max.Y-1:
		return circle(x-r.i.Min.X, y-(r.i.Max.Y-1), r.br)
	case x > r.i.Max.X-1 && y > r.i.Max.Y-1:
		return circle(x-(r.i.Max.X-1), y-(r.i.Max.Y-1), r.br)
	default:
		return color.Opaque
	}
}
func circle(x, y, r int) color.Alpha16 {
	xxyy := float64(x)*float64(x) + float64(y)*float64(y)
	if xxyy > float64((r+1)*(r+1)) {
		return color.Transparent
	} else if xxyy > float64(r*r) {
		return color.Alpha16{uint16(0xFFFF * (1 - math.Sqrt(xxyy) - float64(r)))}
	}
	return color.Opaque
}

var (
	// gopherBlue is the Gopher Blue primary color from the Go color palette.
	//
	// Reference: https://go.dev/s/brandbook.
	gopherBlue = color.NRGBA{0, 173, 216, 255} // #00add8.

	// terminalColor is the color used as the terminal color.
	terminalColor = color.NRGBA{52, 61, 70, 255} // #343d46.

	// shadowColor is the color used as the shadow color.
	shadowColor = color.NRGBA{0, 0, 0, 140} // #0000008c.
)

type realTwitterClient struct {
	twitterAPI *http.Client
}

type realMastodonClient struct {
	client        *madon.Client
	testRecipient string
}

// PostTweet posts a message to a Mastodon account, with specified text, image, and image alt text.
// If the "client" includes a non-empty test recipient, direct the message to that recipient in a
// "direct message", also known as a "private mention".
func (c realMastodonClient) PostTweet(text string, imagePNG []byte, altText string) (tweetURL string, _ error) {
	client := c.client

	visibility := "public"

	// For end-to-end hand testing, send a message to a designated recipient
	if c.testRecipient != "" {
		text = c.testRecipient + "\n" + text
		visibility = "direct"
	}

	// The documentation says that the name parameter can be empty, but at least one
	// Mastodon server disagrees.  Make the name match the media format, just in case
	// that matters.
	att, err := client.UploadMediaReader(bytes.NewReader(imagePNG), "upload.png", altText, "")
	if err != nil {
		return "upload failure", err
	}
	postParams := madon.PostStatusParams{
		Text:        text,
		MediaIDs:    []string{att.ID},
		Visibility:  visibility,
		Sensitive:   false,
		SpoilerText: "",
	}

	status, err := client.PostStatus(postParams)
	if err != nil {
		return "post failure", err
	}
	return status.URL, nil
}

// PostTweet implements the TweetTasks.TwitterClient interface.
func (c realTwitterClient) PostTweet(text string, imagePNG []byte, altText string) (tweetURL string, _ error) {
	// Make a Twitter API call to upload PNG to upload.twitter.com.
	// See https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload.
	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)
	if f, err := w.CreateFormFile("media", "image.png"); err != nil {
		return "", err
	} else if _, err := f.Write(imagePNG); err != nil {
		return "", err
	} else if err := w.Close(); err != nil {
		return "", err
	}
	req, err := http.NewRequest(http.MethodPost, "https://upload.twitter.com/1.1/media/upload.json?media_category=tweet_image", &buf)
	if err != nil {
		return "", err
	}
	req.Header.Set("Content-Type", w.FormDataContentType())
	resp, err := c.twitterAPI.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
		return "", fmt.Errorf("POST /1.1/media/upload.json: non-200 OK status code: %v body: %q", resp.Status, body)
	}
	var media struct {
		ID string `json:"media_id_string"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&media); err != nil {
		return "", err
	}

	// Make a Twitter API call to post a tweet with the uploaded image.
	// See https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets.
	var tweetReq struct {
		Text  string `json:"text"`
		Media struct {
			MediaIDs []string `json:"media_ids"`
		} `json:"media"`
	}
	tweetReq.Text, tweetReq.Media.MediaIDs = text, []string{media.ID}
	buf.Reset()
	if err := json.NewEncoder(&buf).Encode(tweetReq); err != nil {
		return "", err
	}
	resp, err = c.twitterAPI.Post("https://api.twitter.com/2/tweets", "application/json", &buf)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusCreated {
		body, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
		if isTweetTooLong(resp, body) {
			// A friendlier error for a common error type.
			return "", ErrTweetTooLong
		}
		return "", fmt.Errorf("POST /2/tweets: non-201 Created status code: %v body: %q", resp.Status, body)
	}
	var tweetResp struct {
		Data struct {
			ID string
		}
	}
	if err := json.NewDecoder(resp.Body).Decode(&tweetResp); err != nil {
		return "", err
	}
	// Use a generic "username" in the URL since finding it needs another API call.
	// As long as the URL has this format, it will redirect to the canonical username.
	return "https://twitter.com/username/status/" + tweetResp.Data.ID, nil
}

// ErrTweetTooLong is the error when a tweet is too long.
var ErrTweetTooLong = fmt.Errorf("tweet text length exceeded Twitter's limit")

// isTweetTooLong reports whether the Twitter API response is
// known to represent a "Tweet needs to be a bit shorter." error.
// See https://developer.twitter.com/en/support/twitter-api/error-troubleshooting.
func isTweetTooLong(resp *http.Response, body []byte) bool {
	if resp.StatusCode != http.StatusForbidden {
		return false
	}
	var r struct{ Errors []struct{ Code int } }
	if err := json.Unmarshal(body, &r); err != nil {
		return false
	}
	return len(r.Errors) == 1 && r.Errors[0].Code == 186
}

// NewTwitterClient creates a Twitter API client authenticated
// to make Twitter API calls using the provided credentials.
func NewTwitterClient(t secret.TwitterCredentials) realTwitterClient {
	config := oauth1.NewConfig(t.ConsumerKey, t.ConsumerSecret)
	token := oauth1.NewToken(t.AccessTokenKey, t.AccessTokenSecret)
	return realTwitterClient{twitterAPI: config.Client(context.Background(), token)}
}

// NewMastodonClient creates a Mastodon API client authenticated
// to make Mastodon API calls using the provided credentials.
// The resulting client may have been permission-limited at its creation
// (e.g., only allowed to upload media and write posts).
// For tests, use NewTestMastodonClient, which creates private messages
// instead.
func NewMastodonClient(config secret.MastodonCredentials) (realMastodonClient, error) {
	tok := madon.UserToken{AccessToken: config.AccessToken}
	client, err := madon.RestoreApp(config.Application, config.Instance, config.ClientKey, config.ClientSecret, &tok)
	if err != nil {
		return realMastodonClient{}, err
	}
	return realMastodonClient{client, ""}, nil
}

// NewTestMastodonClient creates a client that will DM the announcement to the
// designated recipient for end-to-end testing. config.TestRecipient cannot be empty;
// that would result in a public message, which should not happen unintentionally.
func NewTestMastodonClient(config secret.MastodonCredentials, pmTarget string) (realMastodonClient, error) {
	if pmTarget == "" {
		panic("private message target to NewTestMastodonClient cannot be empty")
	}
	mc, err := NewMastodonClient(config)
	mc.testRecipient = pmTarget
	return mc, err
}
