package allowed

import (
	"fmt"
	"io/ioutil"
	"sort"
	"strings"
	"sync"

	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	fsnotify "gopkg.in/fsnotify.v1"
)

// Allow is used to enforce additional restrictions on who has access to a site,
// eg. members of a group.
type Allow interface {
	// Member returns true if the given email address has access.
	Member(email string) bool
	Emails() []string
}

// AllowedFromList controls access by checking an email address
// against a list of approved domain names and email addresses.
//
// It implements Allow.
type AllowedFromList struct {
	domains map[string]bool
	emails  map[string]bool
}

// NewAllowedFromList creates a new *AllowedFromList from the list of domain names
// and email addresses.
//
// Example:
//   a := NewAllowedFromList([]string{"google.com", "chromium.org", "someone@example.org"})
//
func NewAllowedFromList(emailsAndDomains []string) *AllowedFromList {
	domains := map[string]bool{}
	emails := map[string]bool{}

	for _, entry := range emailsAndDomains {
		trimmed := strings.ToLower(strings.TrimSpace(entry))
		if trimmed == "" {
			continue
		}
		if strings.Contains(trimmed, "@") {
			emails[trimmed] = true
		} else {
			domains[trimmed] = true
		}
	}

	return &AllowedFromList{
		domains: domains,
		emails:  emails,
	}
}

// Member returns true if the given email address is AllowedFromList.
func (a *AllowedFromList) Member(email string) bool {
	parts := strings.Split(email, "@")
	if len(parts) != 2 {
		return false
	}
	if parts[1] == "" {
		return false
	}

	if a.domains[parts[1]] || a.emails[email] {
		return true
	}
	return false
}

func (a *AllowedFromList) Emails() []string {
	ret := make([]string, 0, len(a.emails))
	for k := range a.emails {
		ret = append(ret, k)
	}
	return ret
}

// Googlers creates a new AllowedFromList which restricts to only users logged
// in with an @google.com account.
func Googlers() *AllowedFromList {
	return NewAllowedFromList([]string{"google.com"})
}

// AllowedFromFile implements Allow by reading the list of emails and domains
// from a file. The file is watched for changes and re-read when they occur.
// The file format is one email address or domain name per line.
//
// It implements Allow.
type AllowedFromFile struct {
	filename string
	allowed  *AllowedFromList
	mutex    sync.RWMutex
}

// NewAllowedFromFile creates a new *AllowedFromFile from the given filename.
//
// Example:
//
//	 emails := `fred@example.com
// barney@example.com
// chromium.org`
//   ioutil.WriteFile("/etc/my_app/auth", []byte(emails), 0644)
//   a := NewAllowedFromFile("/etc/my_app/auth")
//
// The presumption is that an AllowedFromFile will be created
// at startup and if creation fails then the application will
// not start.kk
func NewAllowedFromFile(filename string) (*AllowedFromFile, error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, fmt.Errorf("Failed to create watcher: %s", err)
	}
	a := &AllowedFromFile{
		filename: filename,
	}
	if err := a.reload(); err != nil {
		util.Close(watcher)
		return nil, fmt.Errorf("Failed to initially load allowed from file %q: %s", filename, err)
	}
	go func() {
		for {
			select {
			case <-watcher.Events:
				if err := a.reload(); err != nil {
					sklog.Errorf("Failed to reload allowed file %q: %s", filename, err)
				}
			case err := <-watcher.Errors:
				sklog.Errorf("Watcher error %q: %s", filename, err)
			}
		}
	}()
	if err := watcher.Add(filename); err != nil {
		util.Close(watcher)
		return nil, fmt.Errorf("Failed to watch Allowed file %q: %s", filename, err)
	}
	return a, nil
}

func (a *AllowedFromFile) reload() error {
	b, err := ioutil.ReadFile(a.filename)
	if err != nil {
		return err
	}
	newAllowed := NewAllowedFromList(strings.Split(string(b), "\n"))

	a.mutex.Lock()
	defer a.mutex.Unlock()
	a.allowed = newAllowed

	return nil
}

func (a *AllowedFromFile) Member(email string) bool {
	a.mutex.RLock()
	defer a.mutex.RUnlock()

	return a.allowed.Member(email)
}

func (a *AllowedFromFile) Emails() []string {
	a.mutex.RLock()
	defer a.mutex.RUnlock()

	return a.allowed.Emails()
}

// Union is an Allow which includes members of multiple other Allows.
type Union []Allow

func UnionOf(allows ...Allow) Allow {
	return Union(allows)
}

func (allows Union) Member(email string) bool {
	for _, a := range allows {
		if a.Member(email) {
			return true
		}
	}
	return false
}

func (allows Union) Emails() []string {
	emails := util.StringSet{}
	for _, a := range allows {
		emails.AddLists(a.Emails())
	}
	rv := emails.Keys()
	sort.Strings(rv)
	return rv
}
