package blacklist

import (
	"encoding/json"
	"fmt"
	"os"
	"regexp"
	"sync"

	"go.skia.org/infra/go/sklog"

	"go.skia.org/infra/go/git/repograph"
	"go.skia.org/infra/go/util"
)

const (
	MAX_NAME_CHARS = 50
)

var (
	DEFAULT_RULES = []*Rule{}

	ERR_NO_SUCH_RULE = fmt.Errorf("No such rule.")
)

// Blacklist is a struct which contains rules specifying tasks which should
// not be scheduled.
type Blacklist struct {
	backingFile string
	Rules       map[string]*Rule `json:"rules"`
	mtx         sync.RWMutex
}

// Match determines whether the given taskSpec/commit pair matches one of the
// Rules in the Blacklist.
func (b *Blacklist) Match(taskSpec, commit string) bool {
	return b.MatchRule(taskSpec, commit) != ""
}

// MatchRule determines whether the given taskSpec/commit pair matches one of the
// Rules in the Blacklist. Returns the name of the matched Rule or the empty
// string if no Rules match.
func (b *Blacklist) MatchRule(taskSpec, commit string) string {
	b.mtx.RLock()
	defer b.mtx.RUnlock()
	for _, rule := range b.Rules {
		if rule.Match(taskSpec, commit) {
			return rule.Name
		}
	}
	return ""
}

// ensureDefaults adds the necessary default blacklist rules if necessary.
func (b *Blacklist) ensureDefaults() error {
	for _, rule := range DEFAULT_RULES {
		if err := b.removeRule(rule.Name); err != nil {
			if err.Error() != ERR_NO_SUCH_RULE.Error() {
				return err
			}
		}
		if err := b.addRule(rule); err != nil {
			return err
		}
	}
	return nil
}

// writeOut writes the Blacklist to its backing file. Assumes that the caller
// holds a write lock.
func (b *Blacklist) writeOut() error {
	f, err := os.Create(b.backingFile)
	if err != nil {
		return err
	}
	defer util.Close(f)
	return json.NewEncoder(f).Encode(b)
}

// Add adds a new Rule to the Blacklist.
func (b *Blacklist) AddRule(r *Rule, repos repograph.Map) error {
	if err := ValidateRule(r, repos); err != nil {
		return err
	}
	return b.addRule(r)
}

// addRule adds a new Rule to the Blacklist.
func (b *Blacklist) addRule(r *Rule) error {
	b.mtx.Lock()
	defer b.mtx.Unlock()
	if _, ok := b.Rules[r.Name]; ok {
		return fmt.Errorf("Blacklist already contains a rule named %q", r.Name)
	}
	b.Rules[r.Name] = r
	if err := b.writeOut(); err != nil {
		delete(b.Rules, r.Name)
		return err
	}
	return nil
}

// NewCommitRangeRule creates a new Rule which covers a range of commits.
func NewCommitRangeRule(name, user, description string, taskSpecPatterns []string, startCommit, endCommit string, repos repograph.Map) (*Rule, error) {
	_, repoName, _, err := repos.FindCommit(startCommit)
	if err != nil {
		return nil, err
	}
	_, repo2, _, err := repos.FindCommit(endCommit)
	if err != nil {
		return nil, err
	}
	if repo2 != repoName {
		return nil, fmt.Errorf("Commit %s is in a different repo (%s) from %s (%s)", endCommit, repo2, startCommit, repoName)
	}
	repo, ok := repos[repoName]
	if !ok {
		return nil, fmt.Errorf("Unknown repo %s", repoName)
	}
	commits, err := repo.Repo().RevList(fmt.Sprintf("%s..%s", startCommit, endCommit))
	if err != nil {
		return nil, err
	}
	if len(commits) == 0 {
		return nil, fmt.Errorf("No commits in range %s..%s", startCommit, endCommit)
	}

	// `git rev-list ${startCommit}..${endCommit}` returns a list of commits
	// which does not include startCommit but does include endCommit. For
	// blacklisting rules, we want to include startCommit and not endCommit.
	// The rev-list command returns commits in order of newest to oldest, so
	// we remove the first element of the slice (endCommit), and append
	// startCommit to the end.
	commits = append(commits[1:], startCommit)
	if util.In(endCommit, commits) {
		return nil, fmt.Errorf("Failed to adjust commit range; still includes endCommit.")
	}
	if !util.In(startCommit, commits) {
		return nil, fmt.Errorf("Failed to adjust commit range; does not include startCommit.")
	}

	rule := &Rule{
		AddedBy:          user,
		TaskSpecPatterns: taskSpecPatterns,
		Commits:          commits,
		Description:      description,
		Name:             name,
	}
	if err := ValidateRule(rule, repos); err != nil {
		return nil, err
	}
	return rule, nil
}

// removeRule removes the Rule from the Blacklist.
func (b *Blacklist) removeRule(name string) error {
	b.mtx.Lock()
	defer b.mtx.Unlock()
	r, ok := b.Rules[name]
	if !ok {
		return ERR_NO_SUCH_RULE
	}
	delete(b.Rules, name)
	if err := b.writeOut(); err != nil {
		b.Rules[name] = r
		return err
	}
	return nil
}

// RemoveRule removes the Rule from the Blacklist.
func (b *Blacklist) RemoveRule(name string) error {
	for _, r := range DEFAULT_RULES {
		if r.Name == name {
			return fmt.Errorf("Cannot remove built-in rule %q", name)
		}
	}
	return b.removeRule(name)
}

// Rule is a struct which indicates a specific task or set of tasks which
// should not be scheduled.
//
// TaskSpecPatterns consists of regular expressions used to match taskSpecs
// which should not be triggered according to this Rule.
//
// Commits are simply commit hashes for which the rule applies. If the list is
// empty, the Rule applies for all commits.
//
// A Rule should specify TaskSpecPatterns or Commits or both.
type Rule struct {
	AddedBy          string   `json:"added_by"`
	TaskSpecPatterns []string `json:"task_spec_patterns"`
	Commits          []string `json:"commits"`
	Description      string   `json:"description"`
	Name             string   `json:"name"`
}

// ValidateRule returns an error if the given Rule is not valid.
func ValidateRule(r *Rule, repos repograph.Map) error {
	if r.Name == "" {
		return fmt.Errorf("Rules must have a name.")
	}
	if len(r.Name) > MAX_NAME_CHARS {
		return fmt.Errorf("Rule names must be shorter than %d characters. Use the Description field for detailed information.", MAX_NAME_CHARS)
	}
	if r.AddedBy == "" {
		return fmt.Errorf("Rules must have an AddedBy user.")
	}
	if len(r.TaskSpecPatterns) == 0 && len(r.Commits) == 0 {
		return fmt.Errorf("Rules must include a taskSpec pattern and/or a commit/range.")
	}
	for _, c := range r.Commits {
		if _, _, _, err := repos.FindCommit(c); err != nil {
			return err
		}
	}
	return nil
}

// matchTaskSpec determines whether the taskSpec portion of the Rule matches.
func (r *Rule) matchTaskSpec(taskSpec string) bool {
	// If no taskSpecs are specified, then the rule applies for ALL taskSpecs.
	if len(r.TaskSpecPatterns) == 0 {
		return true
	}
	// If any pattern matches the taskSpec, then the rule applies.
	for _, b := range r.TaskSpecPatterns {
		match, err := regexp.MatchString(b, taskSpec)
		if err != nil {
			sklog.Warningf("Rule regexp returned error for input %q: %s: %s", taskSpec, b, err)
			return false
		}
		if match {
			return true
		}
	}
	return false
}

// matchCommit determines whether the commit portion of the Rule matches.
func (r *Rule) matchCommit(commit string) bool {
	// If no commit is specified, then the rule applies for ALL commits.
	k := len(r.Commits)
	if k == 0 {
		return true
	}
	// If at least one commit is specified, do simple string comparisons.
	for _, c := range r.Commits {
		if commit == c {
			return true
		}
	}
	return false
}

// Match returns true iff the Rule matches the given taskSpec and commit.
func (r *Rule) Match(taskSpec, commit string) bool {
	return r.matchTaskSpec(taskSpec) && r.matchCommit(commit)
}

// FromFile returns a Blacklist instance based on the given file. If the file
// does not exist, the Blacklist will be empty and will attempt to use the file
// for writing.
func FromFile(file string) (*Blacklist, error) {
	b := &Blacklist{
		backingFile: file,
		mtx:         sync.RWMutex{},
	}
	f, err := os.Open(file)
	if err != nil {
		if os.IsNotExist(err) {
			b.Rules = map[string]*Rule{}
			if err := b.writeOut(); err != nil {
				return nil, err
			}
		} else {
			return nil, err
		}
	} else {
		defer util.Close(f)
		if err := json.NewDecoder(f).Decode(b); err != nil {
			return nil, err
		}
	}
	if err := b.ensureDefaults(); err != nil {
		return nil, err
	}
	return b, nil
}
