// Copyright 2020 Google Inc.
//
// 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 classifier

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

// Match is the information about a single instance of a detected match.
type Match struct {
	Name            string
	Confidence      float64
	MatchType       string
	Variant         string
	StartLine       int
	EndLine         int
	StartTokenIndex int
	EndTokenIndex   int
}

// Results captures the summary information and matches detected by the
// classifier.
type Results struct {
	Matches         Matches
	TotalInputLines int
}

// Matches is a sortable slice of Match.
type Matches []*Match

// Swap two elements of Matches.
func (d Matches) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (d Matches) Len() int      { return len(d) }
func (d Matches) Less(i, j int) bool {
	di, dj := d[i], d[j]
	// Return matches ordered by confidence
	if di.Confidence != dj.Confidence {
		return di.Confidence > dj.Confidence
	}
	// Licenses of same confidence are ordered by their appearance
	if di.StartTokenIndex != dj.StartTokenIndex {
		return di.StartTokenIndex < dj.StartTokenIndex
	}
	// Should never get here, but tiebreak based on the larger license.
	return di.EndTokenIndex > dj.EndTokenIndex
}

// Match reports instances of the supplied content in the corpus.
func (c *Classifier) match(in []byte) Results {
	id := c.createTargetIndexedDocument(in)

	firstPass := make(map[string]*indexedDocument)
	for l, d := range c.docs {
		sim := id.tokenSimilarity(d)

		if c.tc.traceTokenize(l) {
			c.tc.trace("Token similarity for %s: %.2f", l, sim)
		}

		if sim >= c.threshold {
			firstPass[l] = d
		}
	}

	if len(firstPass) == 0 {
		return Results{
			Matches:         nil,
			TotalInputLines: 0,
		}
	}

	// Perform the expensive work of generating a searchset to look for token runs.
	id.generateSearchSet(c.q)

	var candidates Matches
	for l, d := range firstPass {
		matches := c.findPotentialMatches(d.s, id.s, c.threshold)
		for _, m := range matches {
			startIndex := m.TargetStart
			endIndex := m.TargetEnd
			conf, startOffset, endOffset := c.score(l, id, d, startIndex, endIndex)
			if conf >= c.threshold && (endIndex-startIndex-startOffset-endOffset) > 0 {
				candidates = append(candidates, &Match{
					Name:            LicenseName(l),
					Variant:         variantName(l),
					MatchType:       detectionType(l),
					Confidence:      conf,
					StartLine:       id.Tokens[startIndex+startOffset].Line,
					EndLine:         id.Tokens[endIndex-endOffset-1].Line,
					StartTokenIndex: id.Tokens[startIndex+startOffset].Index,
					EndTokenIndex:   id.Tokens[endIndex-endOffset-1].Index,
				})
			}

		}
	}
	sort.Sort(candidates)
	retain := make([]bool, len(candidates))
	for i, c := range candidates {
		// Filter out overlapping licenses based primarily on confidence. Since
		// the candidates slice is ordered by confidence, we look for overlaps and
		// decide if we retain the record c.

		// For each candidate, only add it to the report unless we have a
		// higher-quality hit that contains these lines. In the case of two
		// licenses having overlap, we consider 'token density' to break ties. If a
		// less confident match of a larger license has more matching tokens than a
		// perfect match of a smaller license, we want to keep that. This handles
		// licenses that include another license as a subtext. NPL contains MPL
		// as a concrete example.

		keep := true
		proposals := make(map[int]bool)
		for j, o := range candidates {
			if j == i {
				break
			}
			// Make sure to only check containment on licenses that are still in consideration at this point.
			if contains(c, o) && retain[j] {
				// The license here can override a previous detection, but that isn't sufficient to be kept
				// on its own. Consider the licenses Xnet, MPL-1.1 and NPL-1.1 in a file that just has MPL-1.1.
				// The confidence rating on NPL-1.1 will cause Xnet to not be retained, which is correct, but it
				// shouldn't be retained if the token confidence for MPL is higher than NPL since the NPL-specific
				// bits are missing.

				ctoks := float64(c.EndTokenIndex - c.StartTokenIndex)
				otoks := float64(o.EndTokenIndex - o.StartTokenIndex)
				cconf := ctoks * c.Confidence
				oconf := otoks * o.Confidence

				// If the two licenses are exactly the same confidence, that means we
				// have an ambiguous detect and should retain both, so the caller can
				// see and resolve the situation.
				if cconf > oconf {
					proposals[j] = false
				} else if oconf > cconf {
					keep = false
				}
			} else if overlaps(c, o) && retain[j] {
				// if the ending and start lines exactly overlap, it's OK to keep both
				if c.StartLine != o.EndLine {
					keep = false
				}
			}

			if !keep {
				break
			}
		}
		if keep {
			retain[i] = true
			for p, v := range proposals {
				retain[p] = v
			}
		}
	}

	var out Matches
	for i, keep := range retain {
		if keep {
			out = append(out, candidates[i])
		}
	}
	return Results{
		Matches:         out,
		TotalInputLines: id.Tokens[len(id.Tokens)-1].Line,
	}
}

// Classifier provides methods for identifying open source licenses in text
// content.
type Classifier struct {
	tc        *TraceConfiguration
	dict      *dictionary
	docs      map[string]*indexedDocument
	threshold float64
	q         int // The value of q for q-grams in this corpus
}

// NewClassifier creates a classifier with an empty corpus.
func NewClassifier(threshold float64) *Classifier {
	classifier := &Classifier{
		tc:        new(TraceConfiguration),
		dict:      newDictionary(),
		docs:      make(map[string]*indexedDocument),
		threshold: threshold,
		q:         computeQ(threshold),
	}
	return classifier
}

// Normalize takes input content and applies the following transforms to aid in
// identifying license content. The return value of this function is
// line-separated text which is the basis for position values returned by the
// classifier.
//
//
// 1. Breaks up long lines of text. This helps with detecting licenses like in
// TODO(wcn):URL reference
//
// 2. Certain ignorable texts are removed to aid matching blocks of text.
// Introductory lines such as "The MIT License" are removed. Copyright notices
// are removed since the parties are variable and shouldn't impact matching.
//
// It is NOT necessary to call this function to simply identify licenses in a
// file. It should only be called to aid presenting this information to the user
// in context (for example, creating diffs of differences to canonical
// licenses).
//
// It is an invariant of the classifier that calling Match(Normalize(in)) will
// return the same results as Match(in).
func (c *Classifier) Normalize(in []byte) []byte {
	text := normalizeDoc(in, false)
	doc := extractDoc(text, false)

	var buf bytes.Buffer

	switch len(doc.Tokens) {
	case 0:
		return nil
	case 1:
		buf.WriteString(doc.Tokens[0].Text)
		return buf.Bytes()
	}

	prevLine := 1
	buf.WriteString(doc.Tokens[0].Text)
	for _, t := range doc.Tokens[1:] {
		// Only write out an EOL token that incremented the line
		if t.Line == prevLine+1 {
			buf.WriteString("\n")
		}

		// Only write tokens that aren't EOL
		if t.Text != eol {
			// Only put a space between tokens if the previous token was on the same
			// line. This prevents spaces after an EOL
			if t.Line == prevLine {
				buf.WriteString(" ")
			}
			buf.WriteString(t.Text)
		}

		prevLine = t.Line
	}
	return buf.Bytes()
}

// LoadLicenses adds the contents of the supplied directory to the corpus of the
// classifier.
func (c *Classifier) LoadLicenses(dir string) error {
	var files []string
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}
		if !strings.HasSuffix(path, "txt") {
			return nil
		}
		files = append(files, path)
		return nil
	})
	if err != nil {
		return err
	}

	for _, f := range files {
		relativePath := strings.Replace(f, dir, "", 1)
		sep := fmt.Sprintf("%c", os.PathSeparator)
		segments := strings.Split(relativePath, sep)
		category, name, variant := segments[1], segments[2], segments[3]
		b, err := ioutil.ReadFile(f)
		if err != nil {
			return err
		}

		c.AddContent(category, name, variant, []byte(string(b)))
	}
	return nil
}

// SetTraceConfiguration installs a tracing configuration for the classifier.
func (c *Classifier) SetTraceConfiguration(in *TraceConfiguration) {
	c.tc = in
	c.tc.init()
}

// Match finds matches within an unknown text. This will not modify the contents
// of the supplied byte slice.
func (c *Classifier) Match(in []byte) Results {
	return c.match(in)
}

// MatchFrom finds matches within the read content.
func (c *Classifier) MatchFrom(in io.Reader) (Results, error) {
	b, err := ioutil.ReadAll(in)
	if err != nil {
		return Results{}, fmt.Errorf("classifier couldn't read: %w", err)
	}
	return c.Match(b), nil
}

func detectionType(in string) string {
	splits := strings.Split(in, fmt.Sprintf("%c", os.PathSeparator))
	return splits[0]
}

func variantName(in string) string {
	splits := strings.Split(in, fmt.Sprintf("%c", os.PathSeparator))
	return splits[2]
}

// LicenseName produces the output name for a license, removing the internal structure
// of the filename in use.
func LicenseName(in string) string {
	splits := strings.Split(in, fmt.Sprintf("%c", os.PathSeparator))
	return splits[1]
}

// contains returns true iff b is completely inside a
func contains(a, b *Match) bool {
	return a.StartLine <= b.StartLine && a.EndLine >= b.EndLine
}

// returns true iff b <= a <= c
func between(a, b, c int) bool {
	return b <= a && a <= c
}

// returns true iff the ranges covered by a and b overlap.
func overlaps(a, b *Match) bool {
	return between(a.StartLine, b.StartLine, b.EndLine) || between(a.EndLine, b.StartLine, b.EndLine)
}
