// Copyright 2021 Google LLC
//
// 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 compliance

import (
	"fmt"
	"io"
	"sort"
	"strings"
	"testing"

	"android/soong/tools/compliance/testfs"
)

const (
	// AOSP starts a test metadata file for Android Apache-2.0 licensing.
	AOSP = `` +
		`package_name: "Android"
license_kinds: "SPDX-license-identifier-Apache-2.0"
license_conditions: "notice"
`

	// GPL starts a test metadata file for GPL 2.0 licensing.
	GPL = `` +
		`package_name: "Free Software"
license_kinds: "SPDX-license-identifier-GPL-2.0"
license_conditions: "restricted"
`

	// Classpath starts a test metadata file for GPL 2.0 with classpath exception licensing.
	Classpath = `` +
		`package_name: "Free Software"
license_kinds: "SPDX-license-identifier-GPL-2.0-with-classpath-exception"
license_conditions: "permissive"
`

	// DependentModule starts a test metadata file for a module in the same package as `Classpath`.
	DependentModule = `` +
		`package_name: "Free Software"
license_kinds: "SPDX-license-identifier-MIT"
license_conditions: "notice"
`

	// LGPL starts a test metadata file for a module with LGPL 2.0 licensing.
	LGPL = `` +
		`package_name: "Free Library"
license_kinds: "SPDX-license-identifier-LGPL-2.0"
license_conditions: "restricted_if_statically_linked"
`

	// MPL starts a test metadata file for a module with MPL 2.0 reciprical licensing.
	MPL = `` +
		`package_name: "Reciprocal"
license_kinds: "SPDX-license-identifier-MPL-2.0"
license_conditions: "reciprocal"
`

	// MIT starts a test metadata file for a module with generic notice (MIT) licensing.
	MIT = `` +
		`package_name: "Android"
license_kinds: "SPDX-license-identifier-MIT"
license_conditions: "notice"
`

	// Proprietary starts a test metadata file for a module with proprietary licensing.
	Proprietary = `` +
		`package_name: "Android"
license_kinds: "legacy_proprietary"
license_conditions: "proprietary"
`

	// ByException starts a test metadata file for a module with by_exception_only licensing.
	ByException = `` +
		`package_name: "Special"
license_kinds: "legacy_by_exception_only"
license_conditions: "by_exception_only"
`
)

var (
	// meta maps test file names to metadata file content without dependencies.
	meta = map[string]string{
		"apacheBin.meta_lic":                 AOSP,
		"apacheLib.meta_lic":                 AOSP,
		"apacheContainer.meta_lic":           AOSP + "is_container: true\n",
		"dependentModule.meta_lic":           DependentModule,
		"gplWithClasspathException.meta_lic": Classpath,
		"gplBin.meta_lic":                    GPL,
		"gplLib.meta_lic":                    GPL,
		"gplContainer.meta_lic":              GPL + "is_container: true\n",
		"lgplBin.meta_lic":                   LGPL,
		"lgplLib.meta_lic":                   LGPL,
		"mitBin.meta_lic":                    MIT,
		"mitLib.meta_lic":                    MIT,
		"mplBin.meta_lic":                    MPL,
		"mplLib.meta_lic":                    MPL,
		"proprietary.meta_lic":               Proprietary,
		"by_exception.meta_lic":              ByException,
	}
)

// newTestNode constructs a test node in the license graph.
func newTestNode(lg *LicenseGraph, targetName string) *TargetNode {
	if tn, alreadyExists := lg.targets[targetName]; alreadyExists {
		return tn
	}
	tn := &TargetNode{name: targetName}
	lg.targets[targetName] = tn
	return tn
}

// newTestCondition constructs a test license condition.
func newTestCondition(conditionName string) LicenseCondition {
	cl := LicenseConditionSetFromNames(conditionName).AsList()
	if len(cl) == 0 {
		panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
	} else if len(cl) != 1 {
		panic(fmt.Errorf("unexpected multiple conditions from condition name: %q: got %d, want 1", conditionName, len(cl)))
	}
	lc := cl[0]
	return lc
}

// newTestConditionSet constructs a test license condition set.
func newTestConditionSet(conditionName []string) LicenseConditionSet {
	cs := LicenseConditionSetFromNames(conditionName...)
	if cs.IsEmpty() {
		panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
	}
	return cs
}

// edge describes test data edges to define test graphs.
type edge struct {
	target, dep string
}

// String returns a string representation of the edge.
func (e edge) String() string {
	return e.target + " -> " + e.dep
}

// byEdge orders edges by target then dep name then annotations.
type byEdge []edge

// Len returns the count of elements in the slice.
func (l byEdge) Len() int { return len(l) }

// Swap rearranges 2 elements of the slice so that each occupies the other's
// former position.
func (l byEdge) Swap(i, j int) { l[i], l[j] = l[j], l[i] }

// Less returns true when the `i`th element is lexicographically less than
// the `j`th element.
func (l byEdge) Less(i, j int) bool {
	if l[i].target == l[j].target {
		return l[i].dep < l[j].dep
	}
	return l[i].target < l[j].target
}

// annotated describes annotated test data edges to define test graphs.
type annotated struct {
	target, dep string
	annotations []string
}

func (e annotated) String() string {
	if e.annotations != nil {
		return e.target + " -> " + e.dep + " [" + strings.Join(e.annotations, ", ") + "]"
	}
	return e.target + " -> " + e.dep
}

func (e annotated) IsEqualTo(other annotated) bool {
	if e.target != other.target {
		return false
	}
	if e.dep != other.dep {
		return false
	}
	if len(e.annotations) != len(other.annotations) {
		return false
	}
	a1 := append([]string{}, e.annotations...)
	a2 := append([]string{}, other.annotations...)
	for i := 0; i < len(a1); i++ {
		if a1[i] != a2[i] {
			return false
		}
	}
	return true
}

// toGraph converts a list of roots and a list of annotated edges into a test license graph.
func toGraph(stderr io.Writer, roots []string, edges []annotated) (*LicenseGraph, error) {
	deps := make(map[string][]annotated)
	for _, root := range roots {
		deps[root] = []annotated{}
	}
	for _, edge := range edges {
		if prev, ok := deps[edge.target]; ok {
			deps[edge.target] = append(prev, edge)
		} else {
			deps[edge.target] = []annotated{edge}
		}
		if _, ok := deps[edge.dep]; !ok {
			deps[edge.dep] = []annotated{}
		}
	}
	fs := make(testfs.TestFS)
	for file, edges := range deps {
		body := meta[file]
		for _, edge := range edges {
			body += fmt.Sprintf("deps: {\n  file: %q\n", edge.dep)
			for _, ann := range edge.annotations {
				body += fmt.Sprintf("  annotations: %q\n", ann)
			}
			body += "}\n"
		}
		fs[file] = []byte(body)
	}

	return ReadLicenseGraph(&fs, stderr, roots)
}

// logGraph outputs a representation of the graph to a test log.
func logGraph(lg *LicenseGraph, t *testing.T) {
	t.Logf("license graph:")
	t.Logf("  targets:")
	for _, target := range lg.Targets() {
		t.Logf("    %s%s in package %q", target.Name(), target.LicenseConditions().String(), target.PackageName())
	}
	t.Logf("  /targets")
	t.Logf("  edges:")
	for _, edge := range lg.Edges() {
		t.Logf("    %s", edge.String())
	}
	t.Logf("  /edges")
	t.Logf("/license graph")
}

// byAnnotatedEdge orders edges by target then dep name then annotations.
type byAnnotatedEdge []annotated

func (l byAnnotatedEdge) Len() int      { return len(l) }
func (l byAnnotatedEdge) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
func (l byAnnotatedEdge) Less(i, j int) bool {
	if l[i].target == l[j].target {
		if l[i].dep == l[j].dep {
			ai := append([]string{}, l[i].annotations...)
			aj := append([]string{}, l[j].annotations...)
			sort.Strings(ai)
			sort.Strings(aj)
			for k := 0; k < len(ai) && k < len(aj); k++ {
				if ai[k] == aj[k] {
					continue
				}
				return ai[k] < aj[k]
			}
			return len(ai) < len(aj)
		}
		return l[i].dep < l[j].dep
	}
	return l[i].target < l[j].target
}

// act describes test data resolution actions to define test action sets.
type act struct {
	actsOn, condition string
}

// String returns a human-readable string representing the test action.
func (a act) String() string {
	return fmt.Sprintf("%s{%s}", a.actsOn, a.condition)
}

// toActionSet converts a list of act test data into a test action set.
func toActionSet(lg *LicenseGraph, data []act) ActionSet {
	as := make(ActionSet)
	for _, a := range data {
		actsOn := newTestNode(lg, a.actsOn)
		cs := newTestConditionSet(strings.Split(a.condition, "|"))
		as[actsOn] = cs
	}
	return as
}

// res describes test data resolutions to define test resolution sets.
type res struct {
	attachesTo, actsOn, condition string
}

// toResolutionSet converts a list of res test data into a test resolution set.
func toResolutionSet(lg *LicenseGraph, data []res) ResolutionSet {
	rmap := make(ResolutionSet)
	for _, r := range data {
		attachesTo := newTestNode(lg, r.attachesTo)
		actsOn := newTestNode(lg, r.actsOn)
		if _, ok := rmap[attachesTo]; !ok {
			rmap[attachesTo] = make(ActionSet)
		}
		cs := newTestConditionSet(strings.Split(r.condition, "|"))
		rmap[attachesTo][actsOn] |= cs
	}
	return rmap
}

// tcond associates a target name with '|' separated string conditions.
type tcond struct {
	target, conditions string
}

// action represents a single element of an ActionSet for testing.
type action struct {
	target *TargetNode
	cs     LicenseConditionSet
}

// String returns a human-readable string representation of the action.
func (a action) String() string {
	return fmt.Sprintf("%s%s", a.target.Name(), a.cs.String())
}

// actionList represents an array of actions and a total order defined by
// target name followed by license condition set.
type actionList []action

// String returns a human-readable string representation of the list.
func (l actionList) String() string {
	var sb strings.Builder
	fmt.Fprintf(&sb, "[")
	sep := ""
	for _, a := range l {
		fmt.Fprintf(&sb, "%s%s", sep, a.String())
		sep = ", "
	}
	fmt.Fprintf(&sb, "]")
	return sb.String()
}

// Len returns the count of elements in the slice.
func (l actionList) Len() int { return len(l) }

// Swap rearranges 2 elements of the slice so that each occupies the other's
// former position.
func (l actionList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }

// Less returns true when the `i`th element is lexicographically less than
// the `j`th element.
func (l actionList) Less(i, j int) bool {
	if l[i].target == l[j].target {
		return l[i].cs < l[j].cs
	}
	return l[i].target.Name() < l[j].target.Name()
}

// asActionList represents the resolved license conditions in a license graph
// as an actionList for comparison in a test.
func asActionList(lg *LicenseGraph) actionList {
	result := make(actionList, 0, len(lg.targets))
	for _, target := range lg.targets {
		cs := target.resolution
		if cs.IsEmpty() {
			continue
		}
		result = append(result, action{target, cs})
	}
	return result
}

// toActionList converts an array of tcond into an actionList for comparison
// in a test.
func toActionList(lg *LicenseGraph, actions []tcond) actionList {
	result := make(actionList, 0, len(actions))
	for _, actn := range actions {
		target := newTestNode(lg, actn.target)
		cs := NewLicenseConditionSet()
		for _, name := range strings.Split(actn.conditions, "|") {
			lc, ok := RecognizedConditionNames[name]
			if !ok {
				panic(fmt.Errorf("Unrecognized test condition name: %q", name))
			}
			cs = cs.Plus(lc)
		}
		result = append(result, action{target, cs})
	}
	return result
}

// confl defines test data for a SourceSharePrivacyConflict as a target name,
// source condition name, privacy condition name triple.
type confl struct {
	sourceNode, share, privacy string
}

// toConflictList converts confl test data into an array of
// SourceSharePrivacyConflict for comparison in a test.
func toConflictList(lg *LicenseGraph, data []confl) []SourceSharePrivacyConflict {
	result := make([]SourceSharePrivacyConflict, 0, len(data))
	for _, c := range data {
		fields := strings.Split(c.share, ":")
		cshare := fields[1]
		fields = strings.Split(c.privacy, ":")
		cprivacy := fields[1]
		result = append(result, SourceSharePrivacyConflict{
			newTestNode(lg, c.sourceNode),
			newTestCondition(cshare),
			newTestCondition(cprivacy),
		})
	}
	return result
}

// checkSameActions compares an actual action set to an expected action set for a test.
func checkSameActions(lg *LicenseGraph, asActual, asExpected ActionSet, t *testing.T) {
	rsActual := make(ResolutionSet)
	rsExpected := make(ResolutionSet)
	testNode := newTestNode(lg, "test")
	rsActual[testNode] = asActual
	rsExpected[testNode] = asExpected
	checkSame(rsActual, rsExpected, t)
}

// checkSame compares an actual resolution set to an expected resolution set for a test.
func checkSame(rsActual, rsExpected ResolutionSet, t *testing.T) {
	t.Logf("actual resolution set: %s", rsActual.String())
	t.Logf("expected resolution set: %s", rsExpected.String())

	actualTargets := rsActual.AttachesTo()
	sort.Sort(actualTargets)

	expectedTargets := rsExpected.AttachesTo()
	sort.Sort(expectedTargets)

	t.Logf("actual targets: %s", actualTargets.String())
	t.Logf("expected targets: %s", expectedTargets.String())

	for _, target := range expectedTargets {
		if !rsActual.AttachesToTarget(target) {
			t.Errorf("unexpected missing target: got AttachesToTarget(%q) is false, want true", target.name)
			continue
		}
		expectedRl := rsExpected.Resolutions(target)
		sort.Sort(expectedRl)
		actualRl := rsActual.Resolutions(target)
		sort.Sort(actualRl)
		if len(expectedRl) != len(actualRl) {
			t.Errorf("unexpected number of resolutions attach to %q: %d elements, %d elements",
				target.name, len(actualRl), len(expectedRl))
			continue
		}
		for i := 0; i < len(expectedRl); i++ {
			if expectedRl[i].attachesTo.name != actualRl[i].attachesTo.name || expectedRl[i].actsOn.name != actualRl[i].actsOn.name {
				t.Errorf("unexpected resolution attaches to %q at index %d: got %s, want %s",
					target.name, i, actualRl[i].asString(), expectedRl[i].asString())
				continue
			}
			expectedConditions := expectedRl[i].Resolves()
			actualConditions := actualRl[i].Resolves()
			if expectedConditions != actualConditions {
				t.Errorf("unexpected conditions apply to %q acting on %q: got %#v with names %s, want %#v with names %s",
					target.name, expectedRl[i].actsOn.name,
					actualConditions, actualConditions.Names(),
					expectedConditions, expectedConditions.Names())
				continue
			}
		}

	}
	for _, target := range actualTargets {
		if !rsExpected.AttachesToTarget(target) {
			t.Errorf("unexpected extra target: got expected.AttachesTo(%q) is false, want true", target.name)
		}
	}
}

// checkResolvesActions compares an actual action set to an expected action set for a test verifying the actual set
// resolves all of the expected conditions.
func checkResolvesActions(lg *LicenseGraph, asActual, asExpected ActionSet, t *testing.T) {
	rsActual := make(ResolutionSet)
	rsExpected := make(ResolutionSet)
	testNode := newTestNode(lg, "test")
	rsActual[testNode] = asActual
	rsExpected[testNode] = asExpected
	checkResolves(rsActual, rsExpected, t)
}

// checkResolves compares an actual resolution set to an expected resolution set for a test verifying the actual set
// resolves all of the expected conditions.
func checkResolves(rsActual, rsExpected ResolutionSet, t *testing.T) {
	t.Logf("actual resolution set: %s", rsActual.String())
	t.Logf("expected resolution set: %s", rsExpected.String())

	actualTargets := rsActual.AttachesTo()
	sort.Sort(actualTargets)

	expectedTargets := rsExpected.AttachesTo()
	sort.Sort(expectedTargets)

	t.Logf("actual targets: %s", actualTargets.String())
	t.Logf("expected targets: %s", expectedTargets.String())

	for _, target := range expectedTargets {
		if !rsActual.AttachesToTarget(target) {
			t.Errorf("unexpected missing target: got AttachesToTarget(%q) is false, want true", target.name)
			continue
		}
		expectedRl := rsExpected.Resolutions(target)
		sort.Sort(expectedRl)
		actualRl := rsActual.Resolutions(target)
		sort.Sort(actualRl)
		if len(expectedRl) != len(actualRl) {
			t.Errorf("unexpected number of resolutions attach to %q: %d elements, %d elements",
				target.name, len(actualRl), len(expectedRl))
			continue
		}
		for i := 0; i < len(expectedRl); i++ {
			if expectedRl[i].attachesTo.name != actualRl[i].attachesTo.name || expectedRl[i].actsOn.name != actualRl[i].actsOn.name {
				t.Errorf("unexpected resolution attaches to %q at index %d: got %s, want %s",
					target.name, i, actualRl[i].asString(), expectedRl[i].asString())
				continue
			}
			expectedConditions := expectedRl[i].Resolves()
			actualConditions := actualRl[i].Resolves()
			if expectedConditions != (expectedConditions & actualConditions) {
				t.Errorf("expected conditions missing from %q acting on %q: got %#v with names %s, want %#v with names %s",
					target.name, expectedRl[i].actsOn.name,
					actualConditions, actualConditions.Names(),
					expectedConditions, expectedConditions.Names())
				continue
			}
		}

	}
	for _, target := range actualTargets {
		if !rsExpected.AttachesToTarget(target) {
			t.Errorf("unexpected extra target: got expected.AttachesTo(%q) is false, want true", target.name)
		}
	}
}
