// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Package expectations provides types and helpers for parsing, updating and
// writing WebGPU expectations files.
//
// See <dawn>/webgpu-cts/expectations.txt for more information.
package expectations

import (
	"fmt"
	"io"

	"reflect"
	"sort"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/container"
	"dawn.googlesource.com/dawn/tools/src/cts/query"
	"dawn.googlesource.com/dawn/tools/src/cts/result"
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
	"dawn.googlesource.com/dawn/tools/src/reducedglob"
)

// Content holds the full content of an expectations file.
type Content struct {
	Chunks []Chunk
	Tags   Tags
}

// Chunk is an optional comment followed by a run of expectations.
// A chunk ends at the first blank line, or at the transition from an
// expectation to a line-comment.
type Chunk struct {
	Comments     []string     // Line comments at the top of the chunk
	Expectations Expectations // Expectations for the chunk
}

// ExpectationType is a Type + enum for whether an Expectation's Query contains globs or not.
type ExpectationType int

const (
	UNDETERMINED ExpectationType = iota
	EXACT
	GLOB
)

// Expectation holds a single expectation line
type Expectation struct {
	Line            int                      // The 1-based line number of the expectation
	Bug             string                   // The associated bug URL for this expectation
	Tags            result.Tags              // Tags used to filter the expectation
	Query           string                   // The CTS query
	Status          []string                 // The expected result status
	Comment         string                   // Optional comment at end of line
	expectationType ExpectationType          // Cached value of whether |Query| is an exact match or not
	globMatcher     *reducedglob.ReducedGlob // Cached matcher for the case where expectationType == GLOB
}

// Expectations are a list of Expectation
type Expectations []Expectation

// Load loads the expectation file at 'path', returning a Content.
func Load(path string, fsReader oswrapper.FilesystemReader) (Content, error) {
	content, err := fsReader.ReadFile(path)
	if err != nil {
		return Content{}, err
	}
	ex, err := Parse(path, string(content))
	if err != nil {
		return Content{}, err
	}
	return ex, nil
}

// Save saves the Content file to 'path'.
func (c *Content) Save(path string, fsWriter oswrapper.FilesystemWriter) error {
	f, err := fsWriter.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()

	return c.Write(f)
}

// Clone makes a deep-copy of the Content.
func (c *Content) Clone() Content {
	chunks := make([]Chunk, len(c.Chunks))
	for i, c := range c.Chunks {
		chunks[i] = c.Clone()
	}
	return Content{chunks, c.Tags.Clone()}
}

// Empty returns true if the Content has no chunks.
func (c *Content) Empty() bool {
	return len(c.Chunks) == 0
}

// Write writes the Content, in textual form, to the writer w.
func (c *Content) Write(w io.Writer) error {
	for i, chunk := range c.Chunks {
		if i > 0 {
			if _, err := fmt.Fprintln(w); err != nil {
				return err
			}
		}
		for _, comment := range chunk.Comments {
			if _, err := fmt.Fprintln(w, comment); err != nil {
				return err
			}
		}
		for _, expectation := range chunk.Expectations {
			if _, err := fmt.Fprintln(w, expectation.AsExpectationFileString()); err != nil {
				return err
			}
		}
	}
	return nil
}

// String returns the Content as a string.
func (c *Content) String() string {
	sb := strings.Builder{}
	c.Write(&sb)
	return sb.String()
}

// Format sorts each chunk of the Content in place.
func (c *Content) Format() {
	for _, chunk := range c.Chunks {
		chunk.Expectations.Sort()
	}
}

// RemoveExpectationsForUnknownTests modifies the Content in place so that all
// contained Expectations apply to tests in the given testlist.
func (c *Content) RemoveExpectationsForUnknownTests(testlist *[]query.Query) error {
	// Converting into a set allows us to much more efficiently check if a
	// non-wildcard expectation is for a valid test.
	knownTestNames := container.NewSet[string]()
	for _, testQuery := range *testlist {
		knownTestNames.Add(testQuery.ExpectationFileString())
	}

	prunedChunkSlice := make([]Chunk, 0)
	for _, chunk := range c.Chunks {
		prunedChunk := chunk.Clone()
		// If we don't have any expectations already, just add the chunk back
		// immediately to avoid removing comments, especially the header.
		if prunedChunk.IsCommentOnly() {
			prunedChunkSlice = append(prunedChunkSlice, prunedChunk)
			continue
		}

		prunedChunk.Expectations = make(Expectations, 0)
		for _, expectation := range chunk.Expectations {
			// We don't actually parse the query string into a Query since wildcards
			// are treated differently between expectations and CTS queries.
			if expectation.IsGlobExpectation() {
				for testName := range knownTestNames {
					if expectation.AppliesToTest(testName) {
						prunedChunk.Expectations = append(prunedChunk.Expectations, expectation)
						break
					}
				}
			} else {
				// We could technically use AppliesToTest() here like we do for glob
				// expectations, but Contains() will be faster due to use of a set.
				if knownTestNames.Contains(expectation.Query) {
					prunedChunk.Expectations = append(prunedChunk.Expectations, expectation)
				}
			}
		}

		if len(prunedChunk.Expectations) > 0 {
			prunedChunkSlice = append(prunedChunkSlice, prunedChunk)
		}
	}

	c.Chunks = prunedChunkSlice
	return nil
}

// IsCommentOnly returns true if the Chunk contains comments and no expectations.
func (c Chunk) IsCommentOnly() bool {
	return len(c.Comments) > 0 && len(c.Expectations) == 0
}

// Clone returns a deep-copy of the Chunk
func (c Chunk) Clone() Chunk {
	comments := make([]string, len(c.Comments))
	copy(comments, c.Comments)
	expectations := make([]Expectation, len(c.Expectations))
	for i, e := range c.Expectations {
		expectations[i] = e.Clone()
	}
	return Chunk{comments, expectations}
}

func (c Chunk) ContainedWithinList(chunkList *[]Chunk) bool {
	for _, otherChunk := range *chunkList {
		if reflect.DeepEqual(c, otherChunk) {
			return true
		}
	}
	return false
}

// IsGlobExpectation returns whether the Expectation is a glob expectation or
// not. Glob-iness is cached after the first call.
func (e *Expectation) IsGlobExpectation() bool {
	if e.expectationType != UNDETERMINED {
		return e.expectationType == GLOB
	}

	// Count the total number of escaped and unescaped wildcard characters. If
	// they do not match, then that means we have at least one glob, which means
	// this is a glob expectation.
	numEscapedWildcards := strings.Count(e.Query, reducedglob.ESCAPED_WILDCARD)
	numNonEscapedWildcards := strings.Count(e.Query, reducedglob.UNESCAPED_WILDCARD)
	if numEscapedWildcards == numNonEscapedWildcards {
		e.expectationType = EXACT
		return false
	}
	e.expectationType = GLOB
	return true
}

// ensureGlobMatcherIsSet creates and caches a reducedglob.ReducedGlob for the
// Expectation's Query field. Should only be called in cases where
// IsGlobExpectation() returns true.
func (e *Expectation) ensureGlobMatcherIsSet() {
	if e.globMatcher != nil {
		return
	}
	if e.expectationType != GLOB {
		panic("ensureGlobMatcherIsSet should only be ever be called when the for glob expectations")
	}
	e.globMatcher = reducedglob.NewReducedGlob(e.Query)
}

// AppliesToResult returns whether the Expectation applies to the test + config
// represented by the Result.
func (e *Expectation) AppliesToResult(r result.Result) bool {
	// Tags apply as long as the Expectation's tags are a subset of the Result's
	// tags.
	tagsApply := r.Tags.ContainsAll(e.Tags)
	queryApplies := e.AppliesToTest(r.Query.ExpectationFileString())

	return tagsApply && queryApplies
}

// AppliesToTest returns whether the Expectation applies to the test |name|.
// This does NOT take into account the tags contained within the Expectation,
// only whether the name matches.
func (e *Expectation) AppliesToTest(name string) bool {
	// The query is a glob expectation, we need to perform a more complex
	// comparison. Otherwise, we can just check for an exact match.
	if e.IsGlobExpectation() {
		e.ensureGlobMatcherIsSet()
		return e.globMatcher.Matchcase(name)
	} else {
		return e.Query == name
	}
}

// AsExpectationFileString returns the human-readable form of the expectation
// that matches the syntax of the expectation files.
func (e *Expectation) AsExpectationFileString() string {
	parts := []string{}
	if e.Bug != "" {
		parts = append(parts, e.Bug)
	}
	if len(e.Tags) > 0 {
		parts = append(parts, fmt.Sprintf("[ %v ]", strings.Join(e.Tags.List(), " ")))
	}
	parts = append(parts, e.Query)
	parts = append(parts, fmt.Sprintf("[ %v ]", strings.Join(e.Status, " ")))
	if e.Comment != "" {
		parts = append(parts, e.Comment)
	}
	return strings.Join(parts, " ")
}

// Clone makes a deep-copy of the Expectation.
func (e *Expectation) Clone() Expectation {
	out := Expectation{
		Line:    e.Line,
		Bug:     e.Bug,
		Query:   e.Query,
		Comment: e.Comment,
	}
	if e.Tags != nil {
		out.Tags = e.Tags.Clone()
	}
	if e.Status != nil {
		out.Status = append([]string{}, e.Status...)
	}
	return out
}

// Compare compares the relative order of a and b, returning:
//
//	-1 if a should come before b
//	 1 if a should come after b
//	 0 if a and b are identical
//
// Note: Only comparing bug, tags, and query (in that order).
func (e *Expectation) Compare(b Expectation) int {
	switch strings.Compare(e.Bug, b.Bug) {
	case -1:
		return -1
	case 1:
		return 1
	}
	switch strings.Compare(result.TagsToString(e.Tags), result.TagsToString(b.Tags)) {
	case -1:
		return -1
	case 1:
		return 1
	}
	switch strings.Compare(e.Query, b.Query) {
	case -1:
		return -1
	case 1:
		return 1
	}
	return 0
}

// ComparePrioritizeQuery is the same as Compare, but compares in the following
// order: query, tags, bug.
func (e *Expectation) ComparePrioritizeQuery(other Expectation) int {
	switch strings.Compare(e.Query, other.Query) {
	case -1:
		return -1
	case 1:
		return 1
	}
	switch strings.Compare(result.TagsToString(e.Tags), result.TagsToString(other.Tags)) {
	case -1:
		return -1
	case 1:
		return 1
	}
	switch strings.Compare(e.Bug, other.Bug) {
	case -1:
		return -1
	case 1:
		return 1
	}
	return 0
}

// Sort sorts the expectations in-place
func (e Expectations) Sort() {
	sort.Slice(e, func(i, j int) bool { return e[i].Compare(e[j]) < 0 })
}

// SortPrioritizeQuery sorts the expectations in-place, prioritizing the query for
// sorting order.
func (e Expectations) SortPrioritizeQuery() {
	sort.Slice(e, func(i, j int) bool { return e[i].ComparePrioritizeQuery(e[j]) < 0 })
}
