// 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"
	"net/url"
	"strings"
	"text/template"
	"time"

	"github.com/dghubble/oauth1"
	"github.com/esimov/stackblur-go"
	"golang.org/x/build/internal/secret"
	"golang.org/x/build/internal/workflow"
	"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 {
	// Version is the Go version that has been released.
	//
	// The version string must use the same format as Go tags. For example:
	// 	• "go1.17.2" for a minor Go release
	// 	• "go1.18" for a major Go release
	// 	• "go1.18beta1" or "go1.18rc1" for a pre-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.16.10".
	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
}

// TweetTasks contains tasks related to the release tweet.
type TweetTasks struct {
	// TwitterClient can be used to post a tweet.
	TwitterClient 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) (tweetURL string, _ error)
	}

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

// TweetRelease posts a tweet announcing a Go release.
// ErrTweetTooLong is returned if the inputs result in a tweet that's too long.
func (t TweetTasks) TweetRelease(ctx *workflow.TaskContext, versions []string, security string, announcement string) (tweetURL string, _ error) {
	if err := oneOrTwoGoVersions(versions); err != nil {
		return "", err
	}

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

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

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

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

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

// tweetText generates the text to use in the announcement
// tweet for release r.
func tweetText(r releaseTweet, 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
		},
	}).Parse(tweetTextTmpl)
	if err != nil {
		return "", err
	}

	// Pick a template name and populate template data
	// for this type of release.
	var (
		name string
		data interface{}
	)
	if i := strings.Index(r.Version, "beta"); i != -1 { // A beta release.
		name, data = "beta", struct {
			Maj, Beta string
			releaseTweet
		}{
			Maj:          r.Version[len("go"):i],
			Beta:         r.Version[i+len("beta"):],
			releaseTweet: r,
		}
	} else if i := strings.Index(r.Version, "rc"); i != -1 { // Release Candidate.
		name, data = "rc", struct {
			Maj, RC string
			releaseTweet
		}{
			Maj:          r.Version[len("go"):i],
			RC:           r.Version[i+len("rc"):],
			releaseTweet: r,
		}
	} else if strings.Count(r.Version, ".") == 1 { // Major release like "go1.X".
		name, data = "major", struct {
			Maj string
			releaseTweet
		}{
			Maj:          r.Version[len("go"):],
			releaseTweet: r,
		}
	} else if strings.Count(r.Version, ".") == 2 { // Minor release like "go1.X.Y".
		name, data = "minor", struct {
			Curr, Prev string
			releaseTweet
		}{
			Curr:         r.Version[len("go"):],
			Prev:         strings.TrimPrefix(r.SecondaryVersion, "go"),
			releaseTweet: r,
		}
	} else {
		return "", fmt.Errorf("unknown version format: %q", r.Version)
	}

	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, data); err != nil {
		return "", err
	}
	return buf.String(), nil
}

const tweetTextTmpl = `{{define "minor" -}}
{{emoji "release"}} Go {{.Curr}} {{with .Prev}}and {{.}} 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 {{.Maj}} Beta {{.Beta}} 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 {{.Maj}} Release Candidate {{.RC}} 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 {{.Maj}} is released!

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

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

{{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 goVersion. It returns the image encoded as PNG,
// and the text displayed in the image.
//
// tweetImage makes an HTTP GET request to the go.dev/dl/?mode=json
// read-only API to select a random release archive to highlight.
func tweetImage(goVersion string, rnd *rand.Rand) (imagePNG []byte, imageText string, _ error) {
	a, err := fetchRandomArchive(goVersion, rnd)
	if err != nil {
		return nil, "", err
	}
	var buf bytes.Buffer
	if err := goCmdTmpl.Execute(&buf, map[string]string{
		"GoVer":    goVersion,
		"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
}

// fetchRandomArchive downloads all release archives for Go version goVer,
// and selects a random archive to showcase in the image that displays
// sample output from the 'go install golang.org/dl/...@latest' command.
func fetchRandomArchive(goVer string, rnd *rand.Rand) (archive WebsiteFile, _ error) {
	archives, err := fetchReleaseArchives(goVer)
	if err != nil {
		return WebsiteFile{}, err
	}
	return archives[rnd.Intn(len(archives))], nil
}

func fetchReleaseArchives(goVer string) (archives []WebsiteFile, _ error) {
	url := "https://go.dev/dl/?mode=json"
	if strings.Contains(goVer, "beta") || strings.Contains(goVer, "rc") ||
		goVer == "go1.17" || goVer == "go1.17.1" || goVer == "go1.11.1" /* For TestTweetRelease. */ {

		url += "&include=all"
	}
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("non-200 OK status code: %v", resp.Status)
	} else if ct := resp.Header.Get("Content-Type"); ct != "application/json" {
		return nil, fmt.Errorf("got Content-Type %q, want %q", ct, "application/json")
	}
	var releases []WebsiteRelease
	err = json.NewDecoder(resp.Body).Decode(&releases)
	if err != nil {
		return nil, err
	}
	for _, r := range releases {
		if r.Version != goVer {
			continue
		}
		var archives []WebsiteFile
		for _, f := range r.Files {
			if f.Kind != "archive" {
				continue
			}
			archives = append(archives, f)
		}
		if len(archives) == 0 {
			return nil, fmt.Errorf("release version %q has 0 archive files", goVer)
		}
		// Return archives.
		return archives, nil
	}
	return nil, fmt.Errorf("release version %q not found", goVer)
}

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

// PostTweet implements the TweetTasks.TwitterClient interface.
func (c realTwitterClient) PostTweet(text string, imagePNG []byte) (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 media/upload: 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 update status with uploaded image.
	// See https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update.
	resp, err = c.twitterAPI.PostForm("https://api.twitter.com/1.1/statuses/update.json", url.Values{
		"status":    []string{text},
		"media_ids": []string{media.ID},
	})
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		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 statuses/update: non-200 OK status code: %v body: %q", resp.Status, body)
	}
	var tweet struct {
		ID   string `json:"id_str"`
		User struct {
			ScreenName string `json:"screen_name"`
		}
	}
	if err := json.NewDecoder(resp.Body).Decode(&tweet); err != nil {
		return "", err
	}
	return "https://twitter.com/" + tweet.User.ScreenName + "/status/" + tweet.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)}
}
