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

import (
	"context"
	"encoding/json"
	"errors"
	"os"
	"path/filepath"
	"strings"
	"time"

	"fmt"
	"net/http"

	"cloud.google.com/go/storage"
	"google.golang.org/api/iterator"

	"golang.org/x/pkgsite-metrics/internal"
	"golang.org/x/pkgsite-metrics/internal/bigquery"
	"golang.org/x/pkgsite-metrics/internal/derrors"
	"golang.org/x/pkgsite-metrics/internal/log"
	"golang.org/x/pkgsite-metrics/internal/osv"
	"golang.org/x/pkgsite-metrics/internal/vulndb"
	"golang.org/x/pkgsite-metrics/internal/vulndbreqs"
)

func (s *Server) handleComputeRequests(w http.ResponseWriter, r *http.Request) (err error) {
	defer derrors.Wrap(&err, "handleComputeRequests")

	ctx := r.Context()
	// Don't use the Server's BigQuery client: it's for the wrong
	// dataset.
	vClient, err := bigquery.NewClientCreate(ctx, s.cfg.ProjectID, vulndbreqs.DatasetName)
	if err != nil {
		return err
	}
	keyName := "projects/" + s.cfg.ProjectID + "/secrets/vulndb-hmac-key"
	hmacKey, err := internal.GetSecret(ctx, keyName)
	if err != nil {
		return err
	}
	err = vulndbreqs.ComputeAndStore(ctx, s.cfg.VulnDBBucketProjectID, vClient, []byte(hmacKey))
	if err != nil {
		return err
	}
	fmt.Fprintf(w, "Successfully computed and stored request counts.\n")
	return nil
}

func (s *Server) handleVulnDB(w http.ResponseWriter, r *http.Request) (err error) {
	defer derrors.Wrap(&err, "handleVulnDB")

	ctx := r.Context()
	dbClient, err := bigquery.NewClientCreate(ctx, s.cfg.ProjectID, vulndb.DatasetName)
	if err != nil {
		return err
	}

	c, err := storage.NewClient(ctx)
	if err != nil {
		return err
	}
	bucket := c.Bucket("go-vulndb")
	if bucket == nil {
		return errors.New("failed to create go-vulndb bucket")
	}

	lmts, err := lastModified(ctx, dbClient)
	if err != nil {
		return err
	}
	entries, err := vulndbEntries(ctx, bucket)
	if err != nil {
		return err
	}

	for _, e := range entries {
		lmt, ok := lmts[e.ID]
		if ok && e.ModifiedTime.Equal(lmt) {
			// Skip adding the entry if nothing has changed in the meantime.
			log.Infof(ctx, "skipping entry %s, it has not been modified", e.ID)
			continue
		}
		if err = writeResult(ctx, false, w, dbClient, vulndb.TableName, e); err != nil {
			return err
		}
	}

	return nil
}

func vulndbEntries(ctx context.Context, bucket *storage.BucketHandle) ([]*vulndb.Entry, error) {
	osvEntries, err := allVulnerabilities(ctx, bucket)
	if err != nil {
		return nil, err
	}
	var entries []*vulndb.Entry
	for _, oe := range osvEntries {
		entries = append(entries, vulndb.Convert(oe))
	}
	return entries, nil
}

// gcsOSVPrefix is the directory under which .json
// files with OSV entries are located.
const gcsOSVPrefix = "ID"

// allVulnerabilities fetches all osv.Entries from GCS bucket located at ID/*.json paths.
func allVulnerabilities(ctx context.Context, bucket *storage.BucketHandle) ([]*osv.Entry, error) {
	var entries []*osv.Entry
	query := &storage.Query{Prefix: gcsOSVPrefix}
	it := bucket.Objects(ctx, query)
	for {
		attrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return nil, err
		}
		// Skip zip files and index.json.
		if !strings.HasSuffix(attrs.Name, ".json") || strings.HasSuffix(attrs.Name, "index.json") {
			continue
		}

		e, err := readEntry(ctx, bucket, attrs.Name)
		if err != nil {
			return nil, err
		}
		entries = append(entries, e)
	}
	return entries, nil
}

func readEntry(ctx context.Context, bucket *storage.BucketHandle, gcsPath string) (*osv.Entry, error) {
	localPath := filepath.Join(os.TempDir(), "binary")
	if err := copyToLocalFile(localPath, false, gcsPath, gcsOpenFileFunc(ctx, bucket)); err != nil {
		return nil, err
	}
	js, err := os.ReadFile(localPath)
	if err != nil {
		return nil, err
	}
	var entry osv.Entry
	if err := json.Unmarshal(js, &entry); err != nil {
		return nil, err
	}
	return &entry, nil
}

func lastModified(ctx context.Context, c *bigquery.Client) (map[string]time.Time, error) {
	es, err := vulndb.ReadMostRecentDB(ctx, c)
	if err != nil {
		return nil, err
	}
	m := make(map[string]time.Time)
	for _, e := range es {
		m[e.ID] = e.ModifiedTime
	}
	return m, nil
}
