// tracetool is a command-line tool for interrogating a tracedb server.
package main

import (
	"context"
	"crypto/md5"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/human"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/trace/service"
	"go.skia.org/infra/go/util"
	"google.golang.org/grpc"
)

// flags
var (
	address = flag.String("address", "localhost:9090", "The address of the traceservice gRPC endpoint.")
	begin   = flag.String("begin", "1w", "Select the commit ids for the range beginning this long ago.")
	end     = flag.String("end", "0s", "Select the commit ids for the range ending this long ago.")
	id      = flag.String("id", "", "Selects the CommitID with an ID that begins with id.")
	regex   = flag.String("regex", "", "A regular expression to match against traceids.")
	verbose = flag.Bool("verbose", false, "Verbose output.")
	only    = flag.Bool("only", false, "If true then only print values, otherwise print keys and values.")
	showMD5 = flag.Bool("md5", false, "If true then include the MD5 hash value for each commit id to compare across databases. Warning: Slow !")
)

var Usage = func() {
	fmt.Printf(`Usage: tracetool <command> [OPTIONS]...
Inspect and interrogate a running tracedb server.

Commands:

  ls        	List all the commit ids for the given time range.

            	Flags: --begin --end --md5

  count     	Return the number of samples stored for all commits in the given time range.

            	Flags: --begin --end

  ping      	Call the Ping service method every 1s.

  sample    	Get a sampling of values for the given ID.
            	Flags: --begin --end --id --regex --only

            	The first commitid with an ID that begins with the value of --id
            	will be loaded and a sampling of 10 values will be displayed.

  param_grep  Find parameter values that match a regular expression.
  						Flags: --begin --end --regex

	  					It loads all commits in the defined range and matches the
	  					parameter values of each trace in those commits against the
	  					regular expression. For each commit it outputs the paramaters
	  					and their values that match the regex.

  value_grep  Find commits where at least one value matches a regular expression.
  						Flags: --begin --end --regex --verbose

	  					It loads all commits in the defined range and matches the
	  					values of each trace in those commits against the
	  					regular expression. For each commit it outputs the values of the
	  					"name" parameter across traces.
	  					This only makes sense for Gold data since the digests are stored
	  					strings.

Examples:

  To list all the commits for the first 6 days of the previous week:

    tracetool ls -begin 1w -end 1d

  To count all the values for every commit id in the last day:

    tracetool -begin 1d

Flags:

`)
	flag.PrintDefaults()
}

func _list(client traceservice.TraceServiceClient) (*traceservice.ListResponse, error) {
	req := &traceservice.ListRequest{}
	now := time.Now()
	b, err := human.ParseDuration(*begin)
	if err != nil {
		return nil, fmt.Errorf("Invalid begin value: %s", err)
	}
	e, err := human.ParseDuration(*end)
	if err != nil {
		return nil, fmt.Errorf("Invalid begin value: %s", err)
	}

	req.Begin = now.Add(-b).Unix()
	req.End = now.Add(-e).Unix()
	if *verbose {
		fmt.Printf("Requesting from %s to %s\n", now.Add(-b), now.Add(-e))
	}
	return client.List(context.Background(), req)
}

func count(client traceservice.TraceServiceClient) {
	listResp, err := _list(client)
	if err != nil {
		fmt.Printf("Failed to retrieve the list: %s\n", err)
		return
	}
	for _, cid := range listResp.Commitids {
		if *id != "" && !strings.HasPrefix(cid.Id, *id) {
			continue
		}
		req := &traceservice.GetValuesRequest{
			Commitid: cid,
		}
		resp, err := client.GetValues(context.Background(), req)
		if err != nil {
			fmt.Printf("Failed to retrieve values: %s", err)
			return
		}
		fmt.Printf("%s  %s  %s: Count %d\n", cid.Id, cid.Source, time.Unix(cid.Timestamp, 0), len(resp.Values))
	}
}

func list(client traceservice.TraceServiceClient) {
	resp, err := _list(client)
	if err != nil {
		sklog.Fatalf("Failed to retrieve the list: %s\n", err)
	}

	for _, cid := range resp.Commitids {
		if *id != "" && !strings.HasPrefix(cid.Id, *id) {
			continue
		}
		fmt.Printf("%s  %s  %s", cid.Id, cid.Source, time.Unix(cid.Timestamp, 0).UTC())
		if *showMD5 {
			fmt.Printf(" %s", calcMD5FromValues(client, cid))
		}
		fmt.Printf("\n")
	}
}

// calcMD5FromValues loads the values for the given commit ID and sorts the bytes of the
// values in lexicographical order and calculates the hash. This can be used to compare
// commit values across databases.
func calcMD5FromValues(client traceservice.TraceServiceClient, cid *traceservice.CommitID) string {
	req := &traceservice.GetValuesRequest{Commitid: cid}
	resp, err := client.GetValues(context.Background(), req)
	if err != nil {
		sklog.Fatalf("Failed to retrieve value: %s", err)
	}

	sortedStr := make([]string, 0, len(resp.Values))
	for _, val := range resp.Values {
		sortedStr = append(sortedStr, string(val.Value))
	}
	sort.Strings(sortedStr)

	ret := md5.New()
	for _, val := range sortedStr {
		_, err := ret.Write([]byte(val))
		if err != nil {
			sklog.Fatalf("Error writint to MD5: %s", err)
		}
	}
	return fmt.Sprintf("%x", ret.Sum(nil))
}

func _pingStep(ctx context.Context, req *traceservice.Empty, client traceservice.TraceServiceClient) {
	begin := time.Now()
	_, err := client.Ping(ctx, req)
	end := time.Now()
	if err != nil {
		fmt.Printf("Failure: %s\n", err)
	} else {
		fmt.Printf("Success: time=%s\n", end.Sub(begin))
	}
}

func ping(client traceservice.TraceServiceClient) {
	ctx := context.Background()
	req := &traceservice.Empty{}
	_pingStep(ctx, req, client)
	for range time.Tick(time.Second) {
		_pingStep(ctx, req, client)
	}
}

// converter is a func that will convert the raw byte slice returned into the correct type.
type converter func([]byte) interface{}

// goldConverter in an implementation of converter for digests (strings).
func goldConverter(b []byte) interface{} {
	return string(b)
}

func sample(client traceservice.TraceServiceClient) {
	// Get all the CommitIDs in the given time range.
	listResp, err := _list(client)
	if err != nil {
		fmt.Printf("Failed to retrieve the list: %s\n", err)
		return
	}

	for _, cid := range listResp.Commitids {
		if *id != "" && !strings.HasPrefix(cid.Id, *id) {
			continue
		}
		req := &traceservice.GetValuesRequest{
			Commitid: cid,
		}
		resp, err := client.GetValues(context.Background(), req)
		if err != nil {
			fmt.Printf("Failed to retrieve values: %s", err)
			return
		}
		if *regex == "" {
			// Dump a sample of at most 10 values along with their traceids.
			N := 10
			if len(resp.Values) < N {
				N = len(resp.Values)
			}
			for i := 0; i < N; i++ {
				pair := resp.Values[rand.Intn(len(resp.Values))]
				if *only {
					fmt.Printf("%v\n", goldConverter(pair.Value))
				} else {
					fmt.Printf("%110s  -  %v\n", pair.Key, goldConverter(pair.Value))
				}
			}
		} else {
			r, err := regexp.Compile(*regex)
			if err != nil {
				fmt.Printf("Invalid value for regex %q: %s\n", *regex, err)
			}
			for _, pair := range resp.Values {
				if r.MatchString(pair.Key) {
					if *only {
						fmt.Printf("%v\n", goldConverter(pair.Value))
					} else {
						fmt.Printf("%110s  -  %v\n", pair.Key, goldConverter(pair.Value))
					}
				}
			}
		}
	}
}

func param_grep(client traceservice.TraceServiceClient) {
	if *regex == "" {
		sklog.Fatalf("No regex given for param_grep")
	}
	r, err := regexp.Compile(*regex)
	if err != nil {
		sklog.Fatalf("Invalid value for regex %q: %s\n", *regex, err)
	}

	ctx := context.Background()
	resp, err := _list(client)
	if err != nil {
		sklog.Fatalf("Failed to retrieve the list: %s\n", err)
	}

	for _, cid := range resp.Commitids {
		traceIdsResp, err := client.GetValues(ctx, &traceservice.GetValuesRequest{Commitid: cid})
		if err != nil {
			sklog.Errorf("Could not get trace ids: %s", err)
			continue
		}

		traceIds := make([]string, 0, len(traceIdsResp.Values))
		for _, valuePair := range traceIdsResp.Values {
			traceIds = append(traceIds, valuePair.Key)
		}

		paramsResp, err := client.GetParams(ctx, &traceservice.GetParamsRequest{Traceids: traceIds})
		if err != nil {
			sklog.Errorf("Unable to retrieve params for %s. Error: %s", cid, err)
			continue
		}

		result := make(map[string]bool, len(paramsResp.Params))
		for _, p := range paramsResp.Params {
			for key, val := range p.Params {
				if r.MatchString(val) {
					result[fmt.Sprintf("%s = %s", key, val)] = true
				}
			}
		}

		fmt.Printf("%.3d %s  %s  %s \n", len(result), cid.Id, cid.Source, time.Unix(cid.Timestamp, 0))
		for p := range result {
			fmt.Printf("       %s\n", p)
		}
	}
}

func value_grep(client traceservice.TraceServiceClient) {
	if *regex == "" {
		sklog.Fatalf("No regex given for param_grep")
	}
	r, err := regexp.Compile(*regex)
	if err != nil {
		sklog.Fatalf("Invalid value for regex %q: %s\n", *regex, err)
	}

	ctx := context.Background()
	resp, err := _list(client)
	if err != nil {
		sklog.Fatalf("Failed to retrieve the list: %s\n", err)
	}

	for _, cid := range resp.Commitids {
		traceIdsResp, err := client.GetValues(ctx, &traceservice.GetValuesRequest{Commitid: cid})
		if err != nil {
			sklog.Errorf("Could not get trace ids: %s", err)
			continue
		}

		traceIds := make([]string, 0, len(traceIdsResp.Values))
		for _, valuePair := range traceIdsResp.Values {
			if r.MatchString(string(valuePair.Value)) {
				traceIds = append(traceIds, valuePair.Key)
			}
		}

		if len(traceIds) == 0 {
			if *verbose {
				fmt.Printf("NOT FOUND IN %s  %s  %s\n", cid.Id, cid.Source, time.Unix(cid.Timestamp, 0))
			}
			continue
		}

		paramsResp, err := client.GetParams(ctx, &traceservice.GetParamsRequest{Traceids: traceIds})
		if err != nil {
			sklog.Errorf("Unable to retrieve params for %s. Error: %s", cid, err)
			continue
		}

		result := map[string]bool{}
		for _, p := range paramsResp.Params {
			if name, ok := p.Params["name"]; ok {
				result[name] = true
			}
		}

		fmt.Printf("%.3d %s  %s  %s : ", len(result), cid.Id, cid.Source, time.Unix(cid.Timestamp, 0))
		for name := range result {
			fmt.Print(name + "  ")
		}
		fmt.Println()
	}
}

func main() {
	rand.Seed(time.Now().Unix())
	// Grab the first argument off of os.Args, the command, before we call flag.Parse.
	if len(os.Args) < 2 {
		Usage()
		return
	}
	cmd := os.Args[1]
	os.Args = append([]string{os.Args[0]}, os.Args[2:]...)

	// Now parge the flags.
	common.Init()

	// Set up a connection to the server.
	conn, err := grpc.Dial(*address, grpc.WithInsecure())
	if err != nil {
		sklog.Fatalf("did not connect: %v", err)
	}
	defer util.Close(conn)
	client := traceservice.NewTraceServiceClient(conn)

	switch cmd {
	case "ls":
		list(client)
	case "ping":
		ping(client)
	case "count":
		count(client)
	case "sample":
		sample(client)
	case "param_grep":
		param_grep(client)
	case "value_grep":
		value_grep(client)
	default:
		fmt.Printf("Unknown command: %s\n", cmd)
		Usage()
	}
}
