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