// 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
// +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
}
