// Copyright 2017 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.

// Reindex repopulates the perfdata SQL database from the original data files in Google Cloud Storage.
//
// Usage:
//
//	reindex [-v] [-db foo.bar/baz] [-bucket name] prefix...
//
// Reindex reindexes all the uploads with IDs starting with the given prefixes.

//go:build cloud

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"

	"cloud.google.com/go/storage"
	_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
	"golang.org/x/build/perfdata/db"
	"golang.org/x/perf/storage/benchfmt"
	"google.golang.org/api/iterator"
)

var (
	dbName  = flag.String("db", "root:@cloudsql(golang-org:us-central1:golang-org)/perfdata?interpolateParams=true", "connect to MySQL `database`")
	bucket  = flag.String("bucket", "golang-perfdata", "read from Google Cloud Storage `bucket`")
	verbose = flag.Bool("v", false, "verbose")
)

func usage() {
	fmt.Fprintf(os.Stderr, `Usage of reindex:
	reindex [flags] prefix...
`)
	flag.PrintDefaults()
	os.Exit(2)
}

func main() {
	log.SetPrefix("reindex: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()
	if *verbose {
		log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
	}

	ctx := context.Background()

	prefixes := flag.Args()
	if len(prefixes) == 0 {
		log.Fatal("no prefixes to reindex")
	}

	d, err := db.OpenSQL("mysql", *dbName)
	if err != nil {
		log.Fatal(err)
	}
	defer d.Close()

	client, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}
	bucket := client.Bucket(*bucket)

	for _, prefix := range prefixes {
		if strings.Index(prefix, "/") >= 0 {
			log.Fatalf("prefix %q cannot contain /", prefix)
		}
		it := bucket.Objects(ctx, &storage.Query{Prefix: "uploads/" + prefix})
		var lastUploadId string
		var files []string
		for {
			objAttrs, err := it.Next()
			if err == iterator.Done {
				break
			}
			if err != nil {
				log.Fatal(err)
			}
			name := strings.TrimPrefix(objAttrs.Name, "uploads/")
			slash := strings.Index(name, "/")
			if slash < 0 {
				log.Printf("ignoring file %q", objAttrs.Name)
			}
			uploadID := name[:slash]
			if lastUploadId != "" && uploadID != lastUploadId {
				if err := reindex(ctx, d, bucket, lastUploadId, files); err != nil {
					log.Fatal(err)
				}
				files = nil
			}
			files = append(files, objAttrs.Name)
			lastUploadId = uploadID
		}
		if len(files) > 0 {
			if err := reindex(ctx, d, bucket, lastUploadId, files); err != nil {
				log.Fatal(err)
			}
		}
	}
}

func reindex(ctx context.Context, db *db.DB, bucket *storage.BucketHandle, uploadID string, files []string) error {
	if *verbose {
		log.Printf("reindexing %q", uploadID)
	}
	u, err := db.ReplaceUpload(uploadID)
	if err != nil {
		return err
	}
	for _, name := range files {
		if err := reindexOne(ctx, u, bucket, name); err != nil {
			return err
		}
	}
	return u.Commit()
}

func reindexOne(ctx context.Context, u *db.Upload, bucket *storage.BucketHandle, name string) error {
	r, err := bucket.Object(name).NewReader(ctx)
	if err != nil {
		return err
	}
	defer r.Close()
	br := benchfmt.NewReader(r)
	for br.Next() {
		if err := u.InsertRecord(br.Result()); err != nil {
			return err
		}
	}
	if err := br.Err(); err != nil {
		return err
	}
	return nil
}
