// Copyright 2022 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 cvelistrepo supports working with the repo
// containing the list of CVEs.
package cvelistrepo

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

	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/filemode"
	"github.com/go-git/go-git/v5/plumbing/object"
	"golang.org/x/vulndb/internal/cveschema"
	"golang.org/x/vulndb/internal/derrors"
)

// URL is the URL of the cvelist repo.
const URL = "https://github.com/CVEProject/cvelist"

// A File is a file in the cvelist repo that contains a CVE.
type File struct {
	DirPath  string
	Filename string
	TreeHash plumbing.Hash
	BlobHash plumbing.Hash
	Year     int
	Number   int
}

// Files returns all the CVE files in the given repo commit, sorted by
// name.
func Files(repo *git.Repository, commit *object.Commit) (_ []File, err error) {
	defer derrors.Wrap(&err, "CVEFiles(%s)", commit.Hash)

	root, err := repo.TreeObject(commit.TreeHash)
	if err != nil {
		return nil, fmt.Errorf("TreeObject: %v", err)
	}
	files, err := walkFiles(repo, root, "", nil)
	if err != nil {
		return nil, err
	}
	sort.Slice(files, func(i, j int) bool {
		// Compare the year and the number, as ints. Using the ID directly
		// would put CVE-2014-100009 before CVE-2014-10001.
		if files[i].Year != files[j].Year {
			return files[i].Year < files[j].Year
		}
		return files[i].Number < files[j].Number
	})
	return files, nil
}

// walkFiles collects CVE files from a repo tree.
func walkFiles(repo *git.Repository, tree *object.Tree, dirpath string, files []File) ([]File, error) {
	for _, e := range tree.Entries {
		if e.Mode == filemode.Dir {
			dir, err := repo.TreeObject(e.Hash)
			if err != nil {
				return nil, err
			}
			files, err = walkFiles(repo, dir, path.Join(dirpath, e.Name), files)
			if err != nil {
				return nil, err
			}
		} else if isCVEFilename(e.Name) {
			// e.Name is CVE-YEAR-NUMBER.json
			year, err := strconv.Atoi(e.Name[4:8])
			if err != nil {
				return nil, err
			}
			number, err := strconv.Atoi(e.Name[9 : len(e.Name)-5])
			if err != nil {
				return nil, err
			}
			files = append(files, File{
				DirPath:  dirpath,
				Filename: e.Name,
				TreeHash: tree.Hash,
				BlobHash: e.Hash,
				Year:     year,
				Number:   number,
			})
		}
	}
	return files, nil
}

// isCVEFilename reports whether name is the basename of a CVE file.
func isCVEFilename(name string) bool {
	return strings.HasPrefix(name, "CVE-") && path.Ext(name) == ".json"
}

// blobReader returns a reader to the blob with the given hash.
func blobReader(repo *git.Repository, hash plumbing.Hash) (io.Reader, error) {
	blob, err := repo.BlobObject(hash)
	if err != nil {
		return nil, err
	}
	return blob.Reader()
}

// FetchCVE fetches the CVE file for cveID from the CVElist repo and returns
// the parsed info.
func FetchCVE(ctx context.Context, repo *git.Repository, cveID string) (_ *cveschema.CVE, err error) {
	defer derrors.Wrap(&err, "FetchCVE(repo, commit, %s)", cveID)
	ref, err := repo.Reference(plumbing.HEAD, true)
	if err != nil {
		return nil, err
	}
	ch := ref.Hash()
	commit, err := repo.CommitObject(ch)
	if err != nil {
		return nil, err
	}
	files, err := Files(repo, commit)
	if err != nil {
		return nil, err
	}
	for _, f := range files {
		if strings.Contains(f.Filename, cveID) {
			cve, err := ParseCVE(repo, f)
			if err != nil {
				return nil, err
			}
			return cve, nil
		}
	}
	return nil, fmt.Errorf("not found")
}

// ParseCVE parses the CVE file f into a CVE.
func ParseCVE(repo *git.Repository, f File) (*cveschema.CVE, error) {
	// Read CVE from repo.
	r, err := blobReader(repo, f.BlobHash)
	if err != nil {
		return nil, err
	}
	cve := &cveschema.CVE{}
	if err := json.NewDecoder(r).Decode(cve); err != nil {
		return nil, err
	}
	return cve, nil
}
