// 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 main

import (
	"context"
	"encoding/json"
	"fmt"
	"path"
	"sort"
	"strings"

	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing/filemode"
	"github.com/go-git/go-git/v5/plumbing/object"
	"golang.org/x/vuln/srv/internal/cveschema"
	"golang.org/x/vuln/srv/internal/derrors"
	"golang.org/x/vuln/srv/internal/gitrepo"
	"golang.org/x/vuln/srv/internal/worker/log"
)

// Run clones the CVEProject/cvelist repository and compares the files to the
// existing triaged-cve-list.
func Run(dirpath string, triaged map[string]string) (err error) {
	ctx := context.Background()
	defer derrors.Wrap(&err, "Run(triaged)")
	var repo *git.Repository
	if dirpath != "" {
		repo, err = gitrepo.Open(ctx, dirpath)
	} else {
		repo, err = gitrepo.Clone(ctx, gitrepo.CVEListRepoURL)
	}
	if err != nil {
		return err
	}
	root, err := gitrepo.Root(repo)
	if err != nil {
		return err
	}
	t := newTriager(triaged)
	log.Infof(ctx, "Finding new Go vulnerabilities from CVE list...")
	if err := walkRepo(repo, root, "", t); err != nil {
		return err
	}
	var newVulns []string
	for cveID, r := range t {
		if r.isGoVuln {
			newVulns = append(newVulns, fmt.Sprintf("%s (%s)", cveID, r.modulePath))
		}
	}
	sort.Strings(newVulns)
	log.Infof(context.Background(), "Found %d new issues from %d CVEs", t.totalVulns(), t.totalCVEs())
	for _, v := range newVulns {
		fmt.Println(v)
	}
	return nil
}

// walkRepo looks at the files in t, recursively, and check if it is a CVE that
// needs to be manually triaged.
func walkRepo(repo *git.Repository, root *object.Tree, dirpath string, t triager) (err error) {
	defer derrors.Wrap(&err, "walkRepo(repo, root, %q, t)", dirpath)
	for _, e := range root.Entries {
		fp := path.Join(dirpath, e.Name)
		if !strings.HasPrefix(fp, "202") {
			continue
		}
		switch e.Mode {
		case filemode.Dir:
			root2, err := repo.TreeObject(e.Hash)
			if err != nil {
				return err
			}
			if err := walkRepo(repo, root2, fp, t); err != nil {
				return err
			}
		default:
			if !strings.HasPrefix(e.Name, "CVE-") {
				continue
			}
			cveID := strings.TrimSuffix(e.Name, ".json")
			if t.contains(cveID) {
				continue
			}
			c, err := parseCVE(repo, e)
			if err != nil {
				return err
			}
			issue, err := triageCVE(c)
			if err != nil {
				return err
			}
			if issue != nil {
				t.add(issue)
			}
		}
	}
	return nil
}

// parseCVEJSON parses a CVE file following the CVE JSON format:
// https://github.com/CVEProject/automation-working-group/blob/master/cve_json_schema/DRAFT-JSON-file-format-v4.md
func parseCVE(r *git.Repository, e object.TreeEntry) (_ *cveschema.CVE, err error) {
	defer derrors.Wrap(&err, "parseCVE(r, e)")
	blob, err := r.BlobObject(e.Hash)
	if err != nil {
		return nil, fmt.Errorf("r.BlobObject: %v", err)
	}
	src, err := blob.Reader()
	if err != nil {
		return nil, fmt.Errorf("blob.Reader: %v", err)
	}
	defer func() {
		cerr := src.Close()
		if err == nil {
			err = cerr
		}
	}()
	var c cveschema.CVE
	d := json.NewDecoder(src)
	if err := d.Decode(&c); err != nil {
		return nil, fmt.Errorf("d.Decode: %v", err)
	}
	if err != nil {
		return nil, err
	}
	return &c, nil
}
