// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package blueprint

import (
	"fmt"
	"slices"
	"sort"
	"strings"

	"github.com/google/blueprint/pathtools"
)

func verifyGlob(key globKey, pattern string, excludes []string, g pathtools.GlobResult) {
	if pattern != g.Pattern {
		panic(fmt.Errorf("Mismatched patterns %q and %q for glob key %q", pattern, g.Pattern, key))
	}
	if len(excludes) != len(g.Excludes) {
		panic(fmt.Errorf("Mismatched excludes %v and %v for glob key %q", excludes, g.Excludes, key))
	}

	for i := range excludes {
		if g.Excludes[i] != excludes[i] {
			panic(fmt.Errorf("Mismatched excludes %v and %v for glob key %q", excludes, g.Excludes, key))
		}
	}
}

func (c *Context) glob(pattern string, excludes []string) ([]string, error) {
	// Sort excludes so that two globs with the same excludes in a different order reuse the same
	// key.  Make a copy first to avoid modifying the caller's version.
	excludes = slices.Clone(excludes)
	sort.Strings(excludes)

	key := globToKey(pattern, excludes)

	// Try to get existing glob from the stored results
	c.globLock.Lock()
	g, exists := c.globs[key]
	c.globLock.Unlock()

	if exists {
		// Glob has already been done, double check it is identical
		verifyGlob(key, pattern, excludes, g)
		// Return a copy so that modifications don't affect the cached value.
		return slices.Clone(g.Matches), nil
	}

	// Get a globbed file list
	result, err := c.fs.Glob(pattern, excludes, pathtools.FollowSymlinks)
	if err != nil {
		return nil, err
	}

	// Store the results
	c.globLock.Lock()
	if g, exists = c.globs[key]; !exists {
		c.globs[key] = result
	}
	c.globLock.Unlock()

	if exists {
		// Getting the list raced with another goroutine, throw away the results and use theirs
		verifyGlob(key, pattern, excludes, g)
		// Return a copy so that modifications don't affect the cached value.
		return slices.Clone(g.Matches), nil
	}

	// Return a copy so that modifications don't affect the cached value.
	return slices.Clone(result.Matches), nil
}

func (c *Context) Globs() pathtools.MultipleGlobResults {
	keys := make([]globKey, 0, len(c.globs))
	for k := range c.globs {
		keys = append(keys, k)
	}

	sort.Slice(keys, func(i, j int) bool {
		if keys[i].pattern != keys[j].pattern {
			return keys[i].pattern < keys[j].pattern
		}
		return keys[i].excludes < keys[j].excludes
	})

	globs := make(pathtools.MultipleGlobResults, len(keys))
	for i, key := range keys {
		globs[i] = c.globs[key]
	}

	return globs
}

// globKey combines a pattern and a list of excludes into a hashable struct to be used as a key in
// a map.
type globKey struct {
	pattern  string
	excludes string
}

// globToKey converts a pattern and an excludes list into a globKey struct that is hashable and
// usable as a key in a map.
func globToKey(pattern string, excludes []string) globKey {
	return globKey{pattern, strings.Join(excludes, "|")}
}
