// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package checklicenses

import (
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"runtime/trace"
	"sort"
	"strings"
)

// Licenses is an object that facilitates operations on each License object in bulk
type Licenses struct {
	licenses []*License
}

// NewLicenses returns a Licenses object with each license pattern loaded from
// the .lic folder location specified in Config
func NewLicenses(ctx context.Context, root string, prohibitedLicenseTypes []string) (*Licenses, error) {
	defer trace.StartRegion(ctx, "NewLicenses").End()
	licensesPath := []string{}
	err := filepath.Walk(root,
		func(path string, info os.FileInfo, err error) error {
			if info.IsDir() {
				return nil
			}
			licensesPath = append(licensesPath, path)
			return nil
		})
	if err != nil {
		return nil, err
	}

	l := &Licenses{}
	for _, path := range licensesPath {
		bytes, err := ioutil.ReadFile(path)
		if err != nil {
			return nil, err
		}
		regex := string(bytes)
		// Update regex to ignore multiple white spaces, newlines, comments.
		// But first, trim whitespace away so we don't include unnecessary
		// comment syntax.
		regex = strings.Trim(regex, "\n ")
		regex = strings.ReplaceAll(regex, "\n", `[\s\\#\*\/]*`)
		regex = strings.ReplaceAll(regex, " ", `[\s\\#\*\/]*`)

		re, err := regexp.Compile(regex)
		if err != nil {
			return nil, fmt.Errorf("%s: %w", path, err)
		}
		base := filepath.Base(path)
		l.licenses = append(
			l.licenses,
			&License{
				pattern:      re,
				Category:     base,
				ValidType:    contains(prohibitedLicenseTypes, filepath.Base(base)),
				matches:      map[string]*Match{},
				matchChannel: make(chan *Match, 10),
			})
	}
	if len(l.licenses) == 0 {
		return nil, errors.New("no licenses")
	}
	// Reorder the files putting fuchsia licenses first, then shortest first.
	sort.Slice(l.licenses, func(i, j int) bool {
		a := strings.Contains(l.licenses[i].Category, "fuchsia")
		b := strings.Contains(l.licenses[j].Category, "fuchsia")
		if a != b {
			return a
		}
		return len(l.licenses[i].pattern.String()) < len(l.licenses[j].pattern.String())
	})
	return l, nil
}

func (l *Licenses) GetFilesWithProhibitedLicenses() []string {
	var filesWithProhibitedLicenses []string
	set := map[string]bool{}
	for _, license := range l.licenses {
		if license.ValidType {
			continue
		}
		for _, match := range license.matches {
			for _, file_path := range match.files {
				if _, found := set[file_path]; !found {
					set[file_path] = true
					filesWithProhibitedLicenses = append(filesWithProhibitedLicenses, file_path)
				}
			}
		}
	}
	return filesWithProhibitedLicenses
}

func (l *Licenses) MatchSingleLicenseFile(data []byte, path string, metrics *Metrics, file_tree *FileTree) {
	// TODO(solomonokinard) deduplicate Match*File()
	for _, license := range l.licenses {
		if m := license.pattern.Find(data); m != nil {
			metrics.increment("num_single_license_file_match")
			license.matchAuthors(string(m), data, path)
			file_tree.Lock()
			file_tree.SingleLicenseFiles[path] = append(file_tree.SingleLicenseFiles[path], license)
			file_tree.Unlock()
		}
	}
}

// MatchFile returns true if any License matches input data
// along with the license that matched. It returns false and nil
// if there were no matches.
func (l *Licenses) MatchFile(data []byte, path string, metrics *Metrics) (bool, *License) {
	for _, license := range l.licenses {
		if m := license.pattern.Find(data); m != nil {
			metrics.increment("num_licensed")
			license.matchAuthors(string(m), data, path)
			return true, license
		}
	}
	return false, nil
}

func contains(matches []string, item string) bool {
	for _, m := range matches {
		if strings.Contains(item, m) {
			return false
		}
	}
	return true
}
