// Copyright 2021 The Go 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 vulncheck

import (
	"fmt"
	"sort"

	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/go/packages/packagestest"
	"golang.org/x/vulndb/osv"
)

type mockClient struct {
	ret map[string][]*osv.Entry
}

func (mc *mockClient) GetByModule(a string) ([]*osv.Entry, error) {
	return mc.ret[a], nil
}

func (mc *mockClient) GetByID(a string) (*osv.Entry, error) {
	return nil, nil
}

// testClient contains the following test vulnerabilities
//   golang.org/amod/avuln.{VulnData.Vuln1, vulnData.Vuln2}
//   golang.org/bmod/bvuln.{Vuln}
var testClient = &mockClient{
	ret: map[string][]*osv.Entry{
		"golang.org/amod": []*osv.Entry{
			{
				ID: "VA",
				Affected: []osv.Affected{{
					Package:           osv.Package{Name: "golang.org/amod/avuln"},
					Ranges:            osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Introduced: "1.0.0"}, {Fixed: "1.0.4"}, {Introduced: "1.1.2"}}}},
					EcosystemSpecific: osv.EcosystemSpecific{Symbols: []string{"VulnData.Vuln1", "VulnData.Vuln2"}},
				}},
			},
		},
		"golang.org/bmod": []*osv.Entry{
			{
				ID: "VB",
				Affected: []osv.Affected{{
					Package:           osv.Package{Name: "golang.org/bmod/bvuln"},
					Ranges:            osv.Affects{{Type: osv.TypeSemver}},
					EcosystemSpecific: osv.EcosystemSpecific{Symbols: []string{"Vuln"}},
				}},
			},
		},
	},
}

func moduleVulnerabilitiesToString(mv moduleVulnerabilities) string {
	var s string
	for _, m := range mv {
		s += fmt.Sprintf("mod: %v\n", m.mod)
		for _, v := range m.vulns {
			s += fmt.Sprintf("\t%v\n", v)
		}
	}
	return s
}

func vulnsToString(vulns []*osv.Entry) string {
	var s string
	for _, v := range vulns {
		s += fmt.Sprintf("\t%v\n", v)
	}
	return s
}

func impGraphToStrMap(ig *ImportGraph) map[string][]string {
	m := make(map[string][]string)
	for _, n := range ig.Packages {
		for _, predId := range n.ImportedBy {
			pred := ig.Packages[predId]
			m[pred.Path] = append(m[pred.Path], n.Path)
		}
	}

	sortStrMap(m)
	return m
}

func reqGraphToStrMap(rg *RequireGraph) map[string][]string {
	m := make(map[string][]string)
	for _, n := range rg.Modules {
		for _, predId := range n.RequiredBy {
			pred := rg.Modules[predId]
			m[pred.Path] = append(m[pred.Path], n.Path)
		}
	}

	sortStrMap(m)
	return m
}

func callGraphToStrMap(cg *CallGraph) map[string][]string {
	type edge struct {
		// src and dest are ids ofr source and
		// destination nodes in a callgraph edge.
		src, dst int
	}
	// seen edges, to avoid repetitions
	seen := make(map[edge]bool)

	funcName := func(fn *FuncNode) string {
		if fn.RecvType == "" {
			return fmt.Sprintf("%s.%s", fn.PkgPath, fn.Name)
		}
		return fmt.Sprintf("%s.%s", fn.RecvType, fn.Name)
	}

	m := make(map[string][]string)
	for _, n := range cg.Funcs {
		fName := funcName(n)
		for _, callsite := range n.CallSites {
			e := edge{src: callsite.Parent, dst: n.ID}
			if seen[e] {
				continue
			}
			caller := cg.Funcs[e.src]
			callerName := funcName(caller)
			m[callerName] = append(m[callerName], fName)
		}
	}

	sortStrMap(m)
	return m
}

func pkgPathToImports(pkgs []*Package) map[string][]string {
	m := make(map[string][]string)
	seen := make(map[*Package]bool)
	var visit func(*Package)
	visit = func(p *Package) {
		if seen[p] {
			return
		}
		seen[p] = true
		var imports []string
		for _, i := range p.Imports {
			imports = append(imports, i.PkgPath)
			visit(i)
		}
		m[p.PkgPath] = imports
	}
	for _, p := range pkgs {
		visit(p)
	}
	sortStrMap(m)
	return m
}

func modulePathToVersion(pkgs []*Package) map[string]string {
	m := make(map[string]string)
	seen := make(map[*Package]bool)
	var visit func(*Package)
	visit = func(p *Package) {
		if seen[p] || p.Module == nil {
			return
		}
		seen[p] = true
		for _, i := range p.Imports {
			visit(i)
		}
		m[p.Module.Path] = p.Module.Version
	}
	for _, p := range pkgs {
		visit(p)
	}
	return m
}

// sortStrMap sorts the map string slice values to make them deterministic.
func sortStrMap(m map[string][]string) {
	for _, strs := range m {
		sort.Strings(strs)
	}
}

func loadPackages(e *packagestest.Exported, patterns ...string) ([]*packages.Package, error) {
	e.Config.Mode |= packages.NeedModule | packages.NeedName | packages.NeedFiles |
		packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedTypes |
		packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps
	return packages.Load(e.Config, patterns...)
}
