package email

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"strings"
	ttemplate "text/template"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	gmail "google.golang.org/api/gmail/v1"
)

var (
	viewActionMarkupTemplate string = `
<div itemscope itemtype="http://schema.org/EmailMessage">
  <div itemprop="potentialAction" itemscope itemtype="http://schema.org/ViewAction">
    <link itemprop="target" href="{{.Link}}"/>
    <meta itemprop="name" content="{{.Name}}"/>
  </div>
  <meta itemprop="description" content="{{.Description}}"/>
</div>
`
	emailTemplate string = `From: {{.From}}
To: {{.To}}
Subject: {{.Subject}}
Content-Type: text/html; charset=UTF-8
References: {{.ThreadingReference}}
In-Reply-To: {{.ThreadingReference}}

<html>
<body>
{{.Markup}}
{{.Body}}
</body>
</html>
`
	viewActionMarkupTemplateParsed *template.Template  = nil
	emailTemplateParsed            *ttemplate.Template = nil
)

func init() {
	viewActionMarkupTemplateParsed = template.Must(template.New("view_action").Parse(viewActionMarkupTemplate))
	emailTemplateParsed = ttemplate.Must(ttemplate.New("email").Parse(emailTemplate))
}

// GMail is an object used for authenticating to the GMail API server.
type GMail struct {
	service *gmail.Service
}

// Message represents a single email message.
type Message struct {
	SenderDisplayName  string
	To                 []string
	Subject            string
	Body               string
	ThreadingReference string
}

// GetViewActionMarkup returns a string that contains the required markup.
func GetViewActionMarkup(link, name, description string) (string, error) {
	markupBytes := new(bytes.Buffer)
	if err := viewActionMarkupTemplateParsed.Execute(markupBytes, struct {
		Link        string
		Name        string
		Description string
	}{
		Link:        link,
		Name:        name,
		Description: description,
	}); err != nil {
		return "", fmt.Errorf("Could not execute template: %v", err)
	}
	return markupBytes.String(), nil
}

// NewGMail returns a new GMail object which is authorized to send email.
func NewGMail(clientId, clientSecret, tokenCacheFile string) (*GMail, error) {
	ts, err := auth.NewTokenSourceFromIdAndSecret(clientId, clientSecret, tokenCacheFile, gmail.GmailComposeScope)
	if err != nil {
		return nil, err
	}
	client := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	service, err := gmail.New(client)
	if err != nil {
		return nil, err
	}
	return &GMail{
		service: service,
	}, nil
}

// ClientSecrets is the structure of a client_secrets.json file that contains info on an installed client.
type ClientSecrets struct {
	Installed ClientConfig `json:"installed"`
}

type ClientConfig struct {
	ClientID     string `json:"client_id"`
	ClientSecret string `json:"client_secret"`
}

// NewFromFiles creates a new GMail object authorized from the given files.
//
// Creates a copy of the token cache file in /tmp since mounted secrets are read-only.
func NewFromFiles(emailTokenCacheFile, emailClientSecretsFile string) (*GMail, error) {
	var clientSecrets ClientSecrets
	err := util.WithReadFile(emailClientSecretsFile, func(f io.Reader) error {
		return json.NewDecoder(f).Decode(&clientSecrets)
	})
	if err != nil {
		sklog.Fatalf("Failed to read client secrets from %q: %s", emailClientSecretsFile, err)
	}
	// Create a copy of the token cache file since mounted secrets are read-only.
	fout, err := ioutil.TempFile("", "")
	if err != nil {
		sklog.Fatalf("Unable to create temp file %q: %s", fout.Name(), err)
	}
	err = util.WithReadFile(emailTokenCacheFile, func(fin io.Reader) error {
		_, err := io.Copy(fout, fin)
		if err != nil {
			err = fout.Close()
		}
		return err
	})
	if err != nil {
		sklog.Fatalf("Failed to write token cache file from %q to %q: %s", emailTokenCacheFile, fout.Name(), err)
	}
	emailTokenCacheFile = fout.Name()

	return NewGMail(clientSecrets.Installed.ClientID, clientSecrets.Installed.ClientSecret, emailTokenCacheFile)
}

// Send an email. Returns the messageId of the sent email.
func (a *GMail) Send(senderDisplayName string, to []string, subject, body, threadingReference string) (string, error) {
	return a.SendWithMarkup(senderDisplayName, to, subject, body, "", threadingReference)
}

// Send an email with gmail markup. Returns the messageId of the sent email.
// Documentation about markups supported in gmail are here: https://developers.google.com/gmail/markup/
// A go-to action example is here: https://developers.google.com/gmail/markup/reference/go-to-action
func (a *GMail) SendWithMarkup(senderDisplayName string, to []string, subject, body, markup, threadingReference string) (string, error) {
	sender := "me"
	// Get email address to use in the from section.
	profile, err := a.service.Users.GetProfile(sender).Do()
	if err != nil {
		return "", fmt.Errorf("Failed to get profile for %s: %v", sender, err)
	}
	fromWithName := fmt.Sprintf("%s <%s>", senderDisplayName, profile.EmailAddress)

	msgBytes := new(bytes.Buffer)
	if err := emailTemplateParsed.Execute(msgBytes, struct {
		From               template.HTML
		To                 string
		Subject            string
		ThreadingReference string
		Body               template.HTML
		Markup             template.HTML
	}{
		From:               template.HTML(fromWithName),
		To:                 strings.Join(to, ","),
		Subject:            subject,
		ThreadingReference: threadingReference,
		Body:               template.HTML(body),
		Markup:             template.HTML(markup),
	}); err != nil {
		return "", fmt.Errorf("Failed to send email; could not execute template: %v", err)
	}
	sklog.Infof("Message to send: %q", msgBytes.String())
	msg := gmail.Message{}
	msg.SizeEstimate = int64(msgBytes.Len())
	msg.Snippet = subject
	msg.Raw = base64.URLEncoding.EncodeToString(msgBytes.Bytes())

	m, err := a.service.Users.Messages.Send(sender, &msg).Do()
	if err != nil {
		return "", fmt.Errorf("Failed to send email: %v", err)
	}
	return m.Id, nil
}

// GetThreadingReference returns the reference string that can be used to thread emails.
func (a *GMail) GetThreadingReference(messageId string) (string, error) {
	// Get the reference from the response headers of messages.get call.
	m, err := a.service.Users.Messages.Get("me", messageId).Do()
	if err != nil {
		return "", fmt.Errorf("Failed to get message data: %v", err)
	}
	reference := ""
	for _, h := range m.Payload.Headers {
		if h.Name == "Message-Id" {
			reference = h.Value
			break
		}
	}
	if reference == "" {
		return "", fmt.Errorf("Could not find \"Message-Id\" header for message Id %s", messageId)
	}
	return reference, nil
}

// SendMessage sends the given Message. Returns the messageId of the sent email.
func (a *GMail) SendMessage(msg *Message) (string, error) {
	return a.Send(msg.SenderDisplayName, msg.To, msg.Subject, msg.Body, msg.ThreadingReference)
}
