// 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

import (
	"fmt"
	"strings"
	"time"

	"dawn.googlesource.com/dawn/tools/src/cts/result"
)

const (
	// Chunk comment for the AddExpectationsForFailingResults path.
	ROLLER_AUTOGENERATED_FAILURES = "# ##ROLLER_AUTOGENERATED_FAILURES##"
)

// AddExpectationsForFailingResults adds new expectations for the provided
// failing results, with the following assumptions:
//   - The provided results do not have existing expectations
//   - Any expectations for invalid/non-existent tests have already been
//     removed
//
// This will:
//   - Reduce result tags down to either:
//     --- Only the most explicit tag from each set
//     --- Only a few very broad tags
//   - Merge identical results together
//   - Add new expectations to the one mutable chunk that is expected to
//     be present in the file.
//   - Sort the mutable chunk's expectations by test name, then tags.
//
// TODO(crbug.com/372730248): Return diagnostics.
func (c *Content) AddExpectationsForFailingResults(results result.List,
	useExplicitTags bool, verbose bool) error {
	// Make a copy of the results. This code mutates the list.
	results = append(result.List{}, results...)

	startTime := time.Now()
	if err := c.removeUnknownTags(&results); err != nil {
		return err
	}
	if verbose {
		fmt.Printf("Removing unknown tags took %s\n", time.Since(startTime).String())
	}

	startTime = time.Now()
	if useExplicitTags {
		if err := c.reduceTagsToMostExplicitOnly(&results); err != nil {
			return err
		}
	} else {
		if err := c.reduceTagsToBroadGroups(&results); err != nil {
			return err
		}
	}
	if verbose {
		fmt.Printf("Reducing tags took %s\n", time.Since(startTime).String())
	}

	// Merge identical results.
	startTime = time.Now()
	results = result.Merge(results)
	if verbose {
		fmt.Printf("Merging identical results took %s\n", time.Since(startTime).String())
	}

	startTime = time.Now()
	if err := c.addExpectationsToMutableChunk(&results); err != nil {
		return err
	}
	if verbose {
		fmt.Printf("Adding expectations took %s\n", time.Since(startTime).String())
	}
	return nil
}

// removeUnknownTags modifies |results| in place so that the Results contained
// within it only use tags that the Content is aware of.
func (c *Content) removeUnknownTags(results *result.List) error {
	*results = results.TransformTags(func(t result.Tags) result.Tags {
		filtered := result.NewTags()
		for tag := range t {
			if _, ok := c.Tags.ByName[tag]; ok {
				filtered.Add(tag)
			}
		}
		return filtered
	})
	return nil
}

// reduceTagsToMostExplicitOnly modifies the given results argument in place
// so that all contained results' tag sets only contain the most explicit tags
// based on the known tag sets contained within the Content.
func (c *Content) reduceTagsToMostExplicitOnly(results *result.List) error {
	for i, res := range *results {
		res.Tags = c.Tags.RemoveLowerPriorityTags(res.Tags)
		(*results)[i] = res
	}
	return nil
}

// reduceTagsToBroadGroups modifies the given results argument in place so that
// all contained results' tag sets only contain several broad but important
// tags.
func (c *Content) reduceTagsToBroadGroups(results *result.List) error {

	osTagSet, gpuTagSet, deviceTagSet, err := c.getBroadTagSets()
	if err != nil {
		return err
	}

	for i, res := range *results {
		// Do an initial culling so only the broad tags are left.
		lowPriorityTags := c.Tags.RemoveHigherPriorityTags(res.Tags)
		chosenTags := result.NewTags()

		// If this is a remote platform, only use the device tag since OS type +
		// GPU vendor can be inferred.
		chosenDeviceTag, err := getAndAssertOneOverlappingTag(deviceTagSet, lowPriorityTags)
		if err == nil {
			chosenTags.Add(chosenDeviceTag)
		} else {
			chosenOsTag, err := getAndAssertOneOverlappingTag(osTagSet, lowPriorityTags)
			if err != nil {
				return err
			}
			chosenTags.Add(chosenOsTag)

			chosenGpuTag, err := getAndAssertOneOverlappingTag(gpuTagSet, lowPriorityTags)
			if err != nil {
				return err
			}
			chosenTags.Add(chosenGpuTag)
		}

		// Modify the result's tags in place.
		res.Tags = chosenTags
		(*results)[i] = res
	}

	return nil
}

// getAndAssertOneOverlappingTag asserts that there is a single tag that is
// shared between the given tags and returns it.
func getAndAssertOneOverlappingTag(validTags, allTags result.Tags) (string, error) {
	overlappingTags := validTags.Intersection(allTags)
	if len(overlappingTags) != 1 {
		return "", fmt.Errorf("Tags %v did not have exactly one overlap with %v", validTags, allTags)
	}
	return overlappingTags.One(), nil
}

// getBroadTagSets retrieves the Content's tag sets which correspond to the three
// primary broad tags: OS, GPU, and device type.
func (c *Content) getBroadTagSets() (result.Tags, result.Tags, result.Tags, error) {
	// Determine which tag sets are the ones we care about. We do this by looking
	// for the tag set that contains one of the well-known tags of that type, e.g.
	// "android", "linux", "mac", or "win" for OS.
	var osTagSet, gpuTagSet, deviceTagSet result.Tags
	// TODO(crbug.com/344014313): Move these known tags into a JSON configuration
	// file for easy modification once dependency injection is available to make
	// testing possible.
	knownOsTags := result.NewTags("android", "linux", "mac", "win")
	knownGpuTags := result.NewTags("amd", "intel", "nvidia", "qualcomm")
	knownDeviceTags := result.NewTags("android-pixel-4", "android-pixel-6",
		"chromeos-board-amd64-generic", "fuchsia-board-qemu-x64")
	for _, tagSet := range c.Tags.Sets {
		if tagSet.Tags.ContainsAny(knownOsTags) {
			osTagSet = tagSet.Tags
		} else if tagSet.Tags.ContainsAny(knownGpuTags) {
			gpuTagSet = tagSet.Tags
		} else if tagSet.Tags.ContainsAny(knownDeviceTags) {
			deviceTagSet = tagSet.Tags
		}
	}

	if osTagSet == nil || gpuTagSet == nil || deviceTagSet == nil {
		return nil, nil, nil, fmt.Errorf("Did not find expected tag sets. Known tags may be out of date. osTagSet: %v, gpuTagSet: %v, deviceTagSet: %v",
			osTagSet, gpuTagSet, deviceTagSet)
	}

	return osTagSet, gpuTagSet, deviceTagSet, nil
}

// addExpectationsToMutableChunk adds expectations for the results contained
// within |results| to the one mutable chunk that  should be in the Content.
// If not found, a new one will be created at the end of the Content.
func (c *Content) addExpectationsToMutableChunk(results *result.List) error {
	// Find the mutable chunk.
	// Chunks are considered immutable by default, unless annotated as
	// ROLLER_AUTOGENERATED_FAILURES.
	mutableTokens := []string{
		ROLLER_AUTOGENERATED_FAILURES,
	}

	// Filter out chunks that do not contain any of the strings in mutableTokens in the comments
	mutableChunkIndices := []int{}
	for i, chunk := range c.Chunks {
		immutable := true

	comments:
		for _, line := range chunk.Comments {
			for _, token := range mutableTokens {
				if strings.Contains(line, token) {
					immutable = false
					break comments
				}
			}
		}

		if !immutable {
			mutableChunkIndices = append(mutableChunkIndices, i)
		}
	}

	var chunkToModify *Chunk
	if len(mutableChunkIndices) > 1 {
		return fmt.Errorf("Expected 1 mutable chunk, found %d", len(mutableChunkIndices))
	} else if len(mutableChunkIndices) == 0 {
		newChunk := Chunk{}
		newChunk.Comments = []string{
			"################################################################################",
			"# Autogenerated Failure expectations. Please triage.",
			ROLLER_AUTOGENERATED_FAILURES,
			"################################################################################",
		}
		c.Chunks = append(c.Chunks, newChunk)
		chunkToModify = &(c.Chunks[len(c.Chunks)-1])
	} else {
		chunkToModify = &(c.Chunks[mutableChunkIndices[0]])
	}

	// Add the new expectations to the mutable chunk.
	for _, res := range *results {
		expectation := Expectation{
			Bug:   "crbug.com/0000",
			Tags:  res.Tags,
			Query: res.Query.ExpectationFileString(),
			Status: []string{
				"Failure",
			},
		}
		chunkToModify.Expectations = append(chunkToModify.Expectations, expectation)
	}

	// Sort the mutable chunk's expectations.
	chunkToModify.Expectations.SortPrioritizeQuery()
	return nil
}
