// Utility that contains methods for dealing with emails.
package util

import (
	"encoding/json"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"strings"

	ctutil "go.skia.org/infra/ct/go/util"
	"go.skia.org/infra/go/email"
	skutil "go.skia.org/infra/go/util"
)

const (
	CT_EMAIL_DISPLAY_NAME = "Cluster Telemetry"
	GMAIL_CACHED_TOKEN    = "ct_gmail_cached_token"
)

var (
	emailClientId     string
	emailClientSecret string
	emailTokenPath    string
)

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

func MailInit(emailClientSecretFile, emailTokenCacheFile string) error {
	var cfg Installed
	err := skutil.WithReadFile(emailClientSecretFile, func(f io.Reader) error {
		return json.NewDecoder(f).Decode(&cfg)
	})
	if err != nil {
		return fmt.Errorf("Failed to read client secrets from %q: %s", emailClientSecretFile, err)
	}
	// Create a copy of the token cache file since mounted secrets are read-only
	// and the access token will need to be updated for the oauth2 flow.
	fout, err := ioutil.TempFile("", "")
	if err != nil {
		return fmt.Errorf("Unable to create temp file: %s", err)
	}
	err = skutil.WithReadFile(emailTokenCacheFile, func(fin io.Reader) error {
		_, err := io.Copy(fout, fin)
		if err != nil {
			err = fout.Close()
		}
		return err
	})
	if err != nil {
		return fmt.Errorf("Failed to write token cache file from %q to %q: %s", emailTokenCacheFile, fout.Name(), err)
	}
	emailTokenCacheFile = fout.Name()
	emailClientId = cfg.Installed.ClientID
	emailClientSecret = cfg.Installed.ClientSecret
	emailTokenPath = emailTokenCacheFile

	return nil
}

// ParseEmails returns an array containing emails from the provided comma
// separated emails string.
func ParseEmails(emails string) []string {
	emailsArr := []string{}
	for _, email := range strings.Split(emails, ",") {
		emailsArr = append(emailsArr, strings.TrimSpace(email))
	}
	return emailsArr
}

// SendEmail sends an email with the specified header and body to the recipients.
func SendEmail(recipients []string, subject, body string) error {
	gmail, err := email.NewGMail(emailClientId, emailClientSecret, emailTokenPath)
	if err != nil {
		return fmt.Errorf("Could not initialize gmail object: %s", err)
	}
	if err := gmail.Send(CT_EMAIL_DISPLAY_NAME, recipients, subject, body); err != nil {
		return fmt.Errorf("Could not send email: %s", err)
	}

	return nil
}

// SendEmailWithMarkup sends an email with the specified header and body to the recipients. It also
// includes gmail markups.
// 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 SendEmailWithMarkup(recipients []string, subject, body, markup string) error {
	gmail, err := email.NewGMail(emailClientId, emailClientSecret, emailTokenPath)
	if err != nil {
		return fmt.Errorf("Could not initialize gmail object: %s", err)
	}
	if err := gmail.SendWithMarkup(CT_EMAIL_DISPLAY_NAME, recipients, subject, body, markup); err != nil {
		return fmt.Errorf("Could not send email with markup: %s", err)
	}

	return nil
}

func GetFailureEmailHtml(runID string) string {
	return fmt.Sprintf(
		"<br/>There were <b>failures</b> in the run. "+
			"Please check the logs of triggered swarming tasks <a href='%s'>here</a>."+
			"<br/>Contact the admins %s for assistance.<br/><br/>",
		fmt.Sprintf(ctutil.SWARMING_RUN_ID_ALL_TASKS_LINK_TEMPLATE, runID), ctutil.CtAdmins)
}

func GetCTPerfEmailHtml(groupName string) string {
	if groupName == "" {
		return ""
	} else {
		return fmt.Sprintf(`
			<br/>See graphed data for your run on <a href='https://ct-perf.skia.org/e/?request_type=1'>ct-perf.skia.org</a> by selecting %s for group_name and then selecting a sub_result and/or test.
			<br/>Example calculated traces:
			<ul>
				<li>ave(filter("group_name=test_group_name&sub_result=rasterize_time__ms_"))</li>
				<li>norm(filter("group_name=test_group_name&sub_result=rasterize_time__ms_&test=http___amazon.co.uk"))</li>
			</ul>
			Documentation for Perf is available <a href='http://go/perf-user-doc'>here</a>.
			<br/><br/>`,
			html.EscapeString(groupName))
	}
}

func SendTaskStartEmail(taskId int64, recipients []string, taskName, runID, runDescription, additionalDescription string) error {
	emailSubject := fmt.Sprintf("%s cluster telemetry task has started (#%d)", taskName, taskId)
	swarmingLogsLink := fmt.Sprintf(ctutil.SWARMING_RUN_ID_ALL_TASKS_LINK_TEMPLATE, runID)

	viewActionMarkup, err := email.GetViewActionMarkup(swarmingLogsLink, "View Logs", "Direct link to the swarming logs")
	if err != nil {
		return fmt.Errorf("Failed to get view action markup: %s", err)
	}
	descriptionHtml := ""
	if runDescription != "" {
		descriptionHtml += fmt.Sprintf("Run description: %s<br/><br/>", runDescription)
	}
	if additionalDescription != "" {
		descriptionHtml += fmt.Sprintf("%s<br/><br/>", additionalDescription)
	}
	bodyTemplate := `
	The %s queued task has started.<br/>
	%s
	You can watch the logs of triggered swarming tasks <a href="%s">here</a>.<br/><br/>
	Thanks!
	`
	emailBody := fmt.Sprintf(bodyTemplate, taskName, descriptionHtml, swarmingLogsLink)
	if err := SendEmailWithMarkup(recipients, emailSubject, emailBody, viewActionMarkup); err != nil {
		return fmt.Errorf("Error while sending task start email: %s", err)
	}
	return nil
}

// SendTasksTerminatedEmail informs the recipients that their CT tasks were terminated and that
// they should reschedule.
func SendTasksTerminatedEmail(recipients []string) error {
	emailSubject := fmt.Sprintf("Cluster telemetry tasks were terminated (%s)", ctutil.GetCurrentTs())
	body := `
	The Cluster telemetry server had to be restarted due to a maintenance issue.<br/>
	This caused all running tasks to be terminated.<br/><br/>
	Please reschedule your tasks. You can redo your tasks by clicking on the redo icon in the 'Runs History' page on http://ct.skia.org.<br/><br/>
	Sorry for the inconvenience!
	`

	if err := SendEmail(recipients, emailSubject, body); err != nil {
		return fmt.Errorf("Error while sending tasks termination email: %s", err)
	}
	return nil
}

// GetSwarmingLogsLink returns HTML snippet that contains a href to the swarming logs.
func GetSwarmingLogsLink(runID string) string {
	return fmt.Sprintf("Swarming logs <a href='%s'>link</a>", fmt.Sprintf(ctutil.SWARMING_RUN_ID_ALL_TASKS_LINK_TEMPLATE, runID))
}
