package notifier

import (
	"context"
	"errors"
	"fmt"

	"cloud.google.com/go/pubsub"
	"go.skia.org/infra/go/chatbot"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/email"
	"go.skia.org/infra/go/util"
)

const (
	EMAIL_FROM_ADDRESS = "noreply@skia.org"
)

// Notifier is an interface used for sending notifications from an AutoRoller.
type Notifier interface {
	// Send the given message to the given thread. This should be safe to
	// run in a goroutine.
	Send(ctx context.Context, thread string, msg *Message) error
}

// Configuration for a Notifier.
type Config struct {
	// Required fields.

	// Configuration for filtering out messages.
	Filter string `json:"filter"`

	// Exactly one of these should be specified.
	Email  *EmailNotifierConfig  `json:"email,omitempty"`
	Chat   *ChatNotifierConfig   `json:"chat,omitempty"`
	PubSub *PubSubNotifierConfig `json:"pubsub,omitempty"`

	// Optional fields.

	// If present, all messages inherit this subject line.
	Subject string `json:"subject,omitempty"`
}

// Validate the Config.
func (c *Config) Validate() error {
	if c.Filter == "" {
		return errors.New("Filter is required.")
	}
	if _, err := ParseFilter(c.Filter); err != nil {
		return err
	}
	n := []util.Validator{}
	if c.Email != nil {
		n = append(n, c.Email)
	}
	if c.Chat != nil {
		n = append(n, c.Chat)
	}
	if c.PubSub != nil {
		n = append(n, c.PubSub)
	}
	if len(n) != 1 {
		return fmt.Errorf("Exactly one notification config must be supplied, but got %d", len(n))
	}
	return n[0].Validate()
}

// Create a Notifier from the Config.
func (c *Config) Create(ctx context.Context, emailer *email.GMail, chatBotConfigReader chatbot.ConfigReader) (Notifier, Filter, string, error) {
	if err := c.Validate(); err != nil {
		return nil, FILTER_SILENT, "", err
	}
	filter, err := ParseFilter(c.Filter)
	if err != nil {
		return nil, FILTER_SILENT, "", err
	}
	var n Notifier
	if c.Email != nil {
		n, err = EmailNotifier(c.Email.Emails, emailer, "")
	} else if c.Chat != nil {
		n, err = ChatNotifier(c.Chat.RoomID, chatBotConfigReader)
	} else if c.PubSub != nil {
		n, err = PubSubNotifier(ctx, c.PubSub.Topic)
	} else {
		return nil, FILTER_SILENT, "", fmt.Errorf("No config specified!")
	}
	if err != nil {
		return nil, FILTER_SILENT, "", err
	}
	return n, filter, c.Subject, nil
}

// Create a copy of this Config.
func (c *Config) Copy(ctx context.Context) *Config {
	configCopy := &Config{
		Filter:  c.Filter,
		Subject: c.Subject,
	}
	if c.Email != nil {
		configCopy.Email = &EmailNotifierConfig{
			Emails: c.Email.Emails,
		}
	}
	if c.Chat != nil {
		configCopy.Chat = &ChatNotifierConfig{
			RoomID: c.Chat.RoomID,
		}
	}
	if c.PubSub != nil {
		configCopy.PubSub = &PubSubNotifierConfig{
			Topic: c.PubSub.Topic,
		}
	}
	return configCopy
}

// Configuration for EmailNotifier.
type EmailNotifierConfig struct {
	// List of email addresses to notify. Required.
	Emails []string `json:"emails"`
}

// Validate the EmailNotifierConfig.
func (c *EmailNotifierConfig) Validate() error {
	if c.Emails == nil || len(c.Emails) == 0 {
		return fmt.Errorf("Emails is required.")
	}
	return nil
}

// emailNotifier is a Notifier implementation which sends email to interested
// parties.
type emailNotifier struct {
	from   string
	gmail  *email.GMail
	markup string
	to     []string
}

// See documentation for Notifier interface.
func (n *emailNotifier) Send(_ context.Context, subject string, msg *Message) error {
	if n.gmail == nil {
		return nil
	}
	return n.gmail.SendWithMarkup(n.from, n.to, subject, msg.Body, n.markup)
}

// EmailNotifier returns a Notifier which sends email to interested parties.
// Sends the same ViewAction markup with each message.
func EmailNotifier(emails []string, emailer *email.GMail, markup string) (Notifier, error) {
	return &emailNotifier{
		from:   EMAIL_FROM_ADDRESS,
		gmail:  emailer,
		markup: markup,
		to:     emails,
	}, nil
}

// Configuration for ChatNotifier.
type ChatNotifierConfig struct {
	RoomID string `json:"room"`
}

// Validate the ChatNotifierConfig.
func (c *ChatNotifierConfig) Validate() error {
	if c.RoomID == "" {
		return fmt.Errorf("RoomID is required.")
	}
	return nil
}

// chatNotifier is a Notifier implementation which sends chat messages.
type chatNotifier struct {
	configReader chatbot.ConfigReader
	roomId       string
}

// See documentation for Notifier interface.
func (n *chatNotifier) Send(_ context.Context, thread string, msg *Message) error {
	return chatbot.SendUsingConfig(msg.Body, n.roomId, thread, n.configReader)
}

// ChatNotifier returns a Notifier which sends email to interested parties.
func ChatNotifier(roomId string, configReader chatbot.ConfigReader) (Notifier, error) {
	return &chatNotifier{
		configReader: configReader,
		roomId:       roomId,
	}, nil
}

// Configuration for a PubSubNotifier.
type PubSubNotifierConfig struct {
	Topic string `json:"topic"`
}

// Validate the PubSubNotifierConfig.
func (c *PubSubNotifierConfig) Validate() error {
	if c.Topic == "" {
		return errors.New("Topic is required.")
	}
	return nil
}

// pubSubNotifier is a Notifier implementation which sends pub/sub messages.
type pubSubNotifier struct {
	topic *pubsub.Topic
}

// See documentation for Notifier interface.
func (n *pubSubNotifier) Send(ctx context.Context, subject string, msg *Message) error {
	res := n.topic.Publish(ctx, &pubsub.Message{
		Attributes: map[string]string{
			"severity": msg.Severity.String(),
			"subject":  subject,
		},
		Data: []byte(msg.Body),
	})
	_, err := res.Get(ctx)
	return err
}

// PubSubNotifier returns a Notifier which sends messages via PubSub.
func PubSubNotifier(ctx context.Context, topic string) (Notifier, error) {
	client, err := pubsub.NewClient(ctx, common.PROJECT_ID)
	if err != nil {
		return nil, err
	}

	// Create the topic if it doesn't exist.
	t := client.Topic(topic)
	if exists, err := t.Exists(ctx); err != nil {
		return nil, err
	} else if !exists {
		t, err = client.CreateTopic(ctx, topic)
		if err != nil {
			return nil, err
		}
	}
	return &pubSubNotifier{
		topic: t,
	}, nil
}
