// Copyright 2023 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 database

import (
	"encoding/json"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"

	"golang.org/x/exp/slices"
	"golang.org/x/vuln/osv"
	"golang.org/x/vulndb/internal/derrors"
	"golang.org/x/vulndb/internal/report"
)

// Load loads a database assuming that path contains a full, valid
// database following the v1 specification.
//
// It errors if:
//   - any required files are missing or invalid
//   - any unexpected files are found in the index/ or ID/ folders
//     (with the exception that ID/index.json, from the legacy spec, is ignored)
//
// Any files present in the top level directory are ignored.
func Load(path string) (_ *Database, err error) {
	defer derrors.Wrap(&err, "Load(%q)", path)

	db, err := RawLoad(filepath.Join(path, idDir))
	if err != nil {
		return nil, err
	}

	requireGzip := true
	if err := db.validateIndex(filepath.Join(path, indexDir), requireGzip); err != nil {
		return nil, err
	}
	if err := db.validateEntries(filepath.Join(path, idDir), requireGzip); err != nil {
		return nil, err
	}
	return db, nil
}

// RawLoad loads a database assuming that vulnsPath contains ".json" files
// representing OSV entries.
// It errors if any of the files cannot be unmarshaled into osv.Entry.
// It does not require any database indexes or gzipped files to be present,
// Directories and non-JSON files are ignored.
// Also, to accommodate the legacy spec, the file "index.json" is ignored
// if present.
func RawLoad(vulnsPath string) (_ *Database, err error) {
	defer derrors.Wrap(&err, "RawLoad(%q)", vulnsPath)

	db, err := New()
	if err != nil {
		return nil, err
	}

	if err := filepath.WalkDir(vulnsPath, func(path string, f fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		fname := f.Name()
		if f.IsDir() ||
			fname == "index.json" ||
			filepath.Ext(fname) != ".json" {
			return nil
		}
		var entry osv.Entry
		if err = report.UnmarshalFromFile(path, &entry); err != nil {
			return fmt.Errorf("could not unmarshal %q: %v", path, err)
		}
		return db.Add(entry)
	}); err != nil {
		return nil, err
	}

	return db, nil
}

func (db *Database) validateIndex(indexPath string, requireGzip bool) (err error) {
	defer derrors.Wrap(&err, "validateIndex(%q)", indexPath)

	// Check that the index files are present and have the correct
	// contents.
	dbPath := filepath.Join(indexPath, dbEndpoint)
	if err := checkFiles(dbPath, db.DB, requireGzip); err != nil {
		return err
	}
	modulesPath := filepath.Join(indexPath, modulesEndpoint)
	if err := checkFiles(modulesPath, db.Modules, requireGzip); err != nil {
		return err
	}
	vulnsPath := filepath.Join(indexPath, vulnsEndpoint)
	if err := checkFiles(vulnsPath, db.Vulns, requireGzip); err != nil {
		return err
	}

	// Check for unexpected files in the index folder.
	expected := []string{
		indexDir,
		dbEndpoint, dbEndpoint + ".gz",
		modulesEndpoint, modulesEndpoint + ".gz",
		vulnsEndpoint, vulnsEndpoint + ".gz",
	}
	return checkNoUnexpectedFiles(indexPath, expected)
}

func (db *Database) validateEntries(idPath string, requireGzip bool) (err error) {
	defer derrors.Wrap(&err, "validateEntries(%q)", idPath)

	expected := []string{
		idDir,
		"index.json", // index.json is OK to accommodate legacy spec
	}
	for _, entry := range db.Entries {
		if err = validateEntry(entry); err != nil {
			return err
		}
		path := filepath.Join(idPath, entry.ID+".json")
		if err = checkFiles(path, entry, requireGzip); err != nil {
			return err
		}
		expected = append(expected, entry.ID+".json", entry.ID+".json.gz")
	}

	return checkNoUnexpectedFiles(idPath, expected)
}

func checkNoUnexpectedFiles(path string, expected []string) error {
	if err := filepath.WalkDir(path, func(path string, f fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if !slices.Contains(expected, f.Name()) {
			return fmt.Errorf("unexpected file %s", f.Name())
		}
		return nil
	}); err != nil {
		return err
	}
	return nil
}

func validateEntry(entry osv.Entry) error {
	if entry.Modified.IsZero() {
		return fmt.Errorf("%s: modified time must be non-zero (found %s)", entry.ID, entry.Modified)
	}
	if entry.Published.After(entry.Modified) {
		return fmt.Errorf("%s: published time (%s) cannot be after modified time (%s)", entry.ID, entry.Published, entry.Modified)
	}
	return nil
}

// checkFiles ensures that filepath and filepath+".gz" exist and
// have contents consistent with v.
// Returns an error if:
//   - any expected files don't exist or v cannot be marshaled
//   - the contents of filepath do not match the result
//     of marshaling v
//   - the uncompressed contents of filepath+".gz" do not match the
//     contents of filepath
func checkFiles(filepath string, v any, requireGzip bool) (err error) {
	defer derrors.Wrap(&err, "checkFiles(%q)", filepath)

	contents, err := os.ReadFile(filepath)
	if err != nil {
		return err
	}
	marshaled, err := json.Marshal(v)
	if err != nil {
		return err
	}
	if string(contents) != string(marshaled) {
		return fmt.Errorf("%s: contents do not match marshaled bytes", filepath)
	}

	if requireGzip {
		gzipped, err := readGzipped(filepath + ".gz")
		if err != nil {
			return err
		}
		if string(contents) != string(gzipped) {
			return fmt.Errorf("%s: contents do not match uncompressed file", filepath+".gz")
		}
	}

	return nil
}
