// Copyright 2020 Google LLC
//
// 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 glob provides file globbing utilities
package glob

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/match"
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
)

// Glob returns all the paths that match the given filepath glob
func Glob(str string, fsReader oswrapper.FilesystemReader) ([]string, error) {
	abs, err := filepath.Abs(str)
	if err != nil {
		return nil, err
	}
	root, glob := "", ""
	// Look for rightmost directory delimiter that's left of a wildcard. Use
	// that to split the 'root' from the match 'glob'.
	for i, c := range abs {
		switch c {
		case filepath.Separator:
			root, glob = abs[:i+1], abs[i+1:]
		case '*', '?':
			test, err := match.New(glob)
			if err != nil {
				return nil, err
			}
			files, err := Scan(root, Config{Paths: searchRules{
				func(path string, cond bool) bool { return test(path) },
			}}, fsReader)
			if err != nil {
				return nil, err
			}
			for i, f := range files {
				files[i] = filepath.Join(root, f) // rel -> abs
			}
			return files, nil
		}
	}
	// No wildcard found. Does the file exist at 'str'?
	if s, err := fsReader.Stat(str); err == nil && !s.IsDir() {
		return []string{str}, nil
	}
	return []string{}, nil
}

// Scan walks all files and subdirectories from root, returning those
// that Config.shouldExamine() returns true for.
func Scan(root string, cfg Config, fsReader oswrapper.FilesystemReader) ([]string, error) {
	files := []string{}
	err := fsReader.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		rel, err := filepath.Rel(root, path)
		if err != nil {
			rel = path
		}

		if rel == ".git" {
			return filepath.SkipDir
		}

		if !cfg.shouldExamine(root, path) {
			return nil
		}

		if !info.IsDir() {
			files = append(files, rel)
		}

		return nil
	})
	if err != nil {
		return nil, err
	}
	return files, nil
}

// Configs is a slice of Config.
type Configs []Config

// Config is used to parse the JSON configuration file.
type Config struct {
	// Paths holds a number of JSON objects that contain either a "includes" or
	// "excludes" key to an array of path patterns.
	// Each path pattern is considered in turn to either include or exclude the
	// file path for license scanning. Pattern use forward-slashes '/' for
	// directory separators, and may use the following wildcards:
	//  ?  - matches any single non-separator character
	//  *  - matches any sequence of non-separator characters
	//  ** - matches any sequence of characters including separators
	//
	// Rules are processed in the order in which they are declared, with later
	// rules taking precedence over earlier rules.
	//
	// All files are excluded before the first rule is evaluated.
	//
	// Example:
	//
	// {
	//   "paths": [
	// 	  { "exclude": [ "out/*", "build/*" ] },
	// 	  { "include": [ "out/foo.txt" ] }
	//   ],
	// }
	Paths searchRules
}

// LoadConfig loads a config file at path.
func LoadConfig(path string, fsReader oswrapper.FilesystemReader) (Config, error) {
	cfgBody, err := fsReader.ReadFile(path)
	if err != nil {
		return Config{}, err
	}
	return ParseConfig(string(cfgBody))
}

// ParseConfig parses the config from a JSON string.
func ParseConfig(config string) (Config, error) {
	d := json.NewDecoder(strings.NewReader(config))
	cfg := Config{}
	if err := d.Decode(&cfg); err != nil {
		return Config{}, err
	}
	return cfg, nil
}

// MustParseConfig parses the config from a JSON string, panicing if the config
// does not parse
func MustParseConfig(config string) Config {
	d := json.NewDecoder(strings.NewReader(config))
	cfg := Config{}
	if err := d.Decode(&cfg); err != nil {
		panic(fmt.Errorf("Failed to parse config: %w\nConfig:\n%v", err, config))
	}
	return cfg
}

// rule is a search path predicate.
// root is the project relative path.
// cond is the value to return if the rule doesn't either include or exclude.
type rule func(path string, cond bool) bool

// searchRules is a ordered list of search rules.
// searchRules is its own type as it has to perform custom JSON unmarshalling.
type searchRules []rule

// UnmarshalJSON unmarshals the array of rules in the form:
// { "include": [ ... ] } or { "exclude": [ ... ] }
func (l *searchRules) UnmarshalJSON(body []byte) error {
	type parsed struct {
		Include []string
		Exclude []string
	}

	p := []parsed{}
	if err := json.NewDecoder(bytes.NewReader(body)).Decode(&p); err != nil {
		return err
	}

	*l = searchRules{}
	for _, rule := range p {
		rule := rule
		switch {
		case len(rule.Include) > 0 && len(rule.Exclude) > 0:
			return fmt.Errorf("Rule cannot contain both include and exclude")
		case len(rule.Include) > 0:
			tests := make([]match.Test, len(rule.Include))
			for i, pattern := range rule.Include {
				test, err := match.New(pattern)
				if err != nil {
					return err
				}
				tests[i] = test
			}
			*l = append(*l, func(path string, cond bool) bool {
				if cond {
					return true
				}
				for _, test := range tests {
					if test(path) {
						return true
					}
				}
				return false
			})
		case len(rule.Exclude) > 0:
			tests := make([]match.Test, len(rule.Exclude))
			for i, pattern := range rule.Exclude {
				test, err := match.New(pattern)
				if err != nil {
					return err
				}
				tests[i] = test
			}
			*l = append(*l, func(path string, cond bool) bool {
				if !cond {
					return false
				}
				for _, test := range tests {
					if test(path) {
						return false
					}
				}
				return true
			})
		}
	}
	return nil
}

// shouldExamine returns true if the file at absPath should be scanned.
func (c Config) shouldExamine(root, absPath string) bool {
	root = filepath.ToSlash(root)       // Canonicalize
	absPath = filepath.ToSlash(absPath) // Canonicalize
	relPath, err := filepath.Rel(root, absPath)
	if err != nil {
		return false
	}
	relPath = filepath.ToSlash(relPath) // Canonicalize

	res := false
	for _, rule := range c.Paths {
		res = rule(relPath, res)
	}

	return res
}
