// Copyright 2022 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 main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"

	// "github.com/dr2chase/debug-server/debug_client"
	"golang.org/x/perf/benchfmt"
	"golang.org/x/perf/internal/benchseries"
	// "runtime"
)

func main() {
	// runtime.OnPanic(debug_client.TryDebug)

	bo := benchseries.BentBuilderOptions()

	var delta bool = false
	var change bool = false
	var values bool = true
	var csv bool = true
	var logScale bool = true
	var boring bool = false

	var pngDir = ""
	var svgDir = ""
	var pdfDir = ""

	var jsonOut = ""
	var jsonIn = ""

	confidence := 0.95
	threshold := 0.02

	flag.StringVar(&bo.Series, "series", bo.Series, "Specify the benchmarking key for the series x-axis")
	flag.StringVar(&bo.Experiment, "experiment", bo.Experiment, "Specify the experient-time key common to trials in an experiment")

	flag.StringVar(&bo.Compare, "compare", bo.Compare, "Specify the benchmark label/key used to select numerator and denominator in the comparison")
	flag.StringVar(&bo.Numerator, "numerator", bo.Numerator, "Numerator value of -compare key")
	flag.StringVar(&bo.Denominator, "denominator", bo.Denominator, "Denominator value of -compare key")

	flag.StringVar(&bo.NumeratorHash, "numerator-hash", bo.NumeratorHash, "Key for hash id of numerators (can be same as denominator-hash)")
	flag.StringVar(&bo.DenominatorHash, "denominator-hash", bo.DenominatorHash, "Key for hash id of denominators (can be same as numerator-hash)")

	flag.StringVar(&bo.Filter, "filter", bo.Filter, "Apply this filter to incoming benchmarks")

	flag.BoolVar(&csv, "csv", csv, "Write the series in CSV form")

	flag.BoolVar(&delta, "delta", delta, "Include the plus-or-minus range in the spreadsheet view")
	flag.BoolVar(&change, "change", change, "Include a change-detected column")
	flag.BoolVar(&values, "values", values, "Include values columns")
	flag.BoolVar(&logScale, "log", logScale, "Use a log scale in the chart")

	flag.StringVar(&pngDir, "png", pngDir, "Directory to write png chart(s) into")
	flag.StringVar(&pdfDir, "pdf", pdfDir, "Directory to write pdf chart(s) into")
	flag.StringVar(&svgDir, "svg", svgDir, "Directory to write svg chart(s) into")

	flag.StringVar(&jsonOut, "jo", jsonOut, "Save benchmarking summary in this json file")
	flag.StringVar(&jsonIn, "ji", jsonIn, "Read benchmarking summary from this json file")

	flag.Float64Var(&confidence, "confidence", confidence, "width of confidence interval")
	flag.Float64Var(&threshold, "threshold", threshold, "threshold for 'it changed' for exact metrics")
	flag.BoolVar(&boring, "boring", boring, "include the boring parts of the history")

	flag.Parse()

	bo.Warn = warn
	seriesBuilder, err := benchseries.NewBuilder(bo)

	if err != nil {
		fail("%v\n", err)
	}

	// Read supplied files
	files := benchfmt.Files{Paths: flag.Args(), AllowStdin: true, AllowLabels: true}
	err = seriesBuilder.AddFiles(files)
	if err != nil {
		fail("%v\n", err)
	}

	// Optionally read JSON of pre-existing comparisons.
	var comparisons []*benchseries.ComparisonSeries

	if jsonIn != "" {
		f, err := os.Open(jsonIn)
		if err != nil {
			fail("Could not read JSON input file (flag -ji), %v", err)
		}
		decoder := json.NewDecoder(f)
		decoder.Decode(&comparisons)
		f.Close()
	}

	// Rearrange into comparisons (not yet doing the statistical work)
	comparisons = seriesBuilder.AllComparisonSeries(comparisons, benchseries.DUPE_REPLACE)

	// Chat about residues, per-table
	for _, t := range comparisons {
		fmt.Fprintf(os.Stderr, "%s residues=", t.Unit)
		first := true
		for _, r := range t.Residues {
			if len(r.Slice) == 1 {
				sep := ","
				if first {
					sep = "["
					first = false
				}
				fmt.Fprintf(os.Stderr, "%s%s=%s", sep, r.S, r.Slice[0])
			}
		}
		for _, r := range t.Residues {
			if len(r.Slice) == 2 {
				sep := ","
				if first {
					sep = "["
					first = false
				}
				fmt.Fprintf(os.Stderr, "%s%s={%s,%s}", sep, r.S, r.Slice[0], r.Slice[1])
			} else if len(r.Slice) > 2 {
				sep := ","
				if first {
					sep = "["
					first = false
				}
				fmt.Fprintf(os.Stderr, "%slen(%s)=%d", sep, r.S, len(r.Slice))
			}

		}
		fmt.Fprintf(os.Stderr, "]\n")
	}

	// Bootstrap and add (missing, if some already supplied by JSON) summaries.
	for _, c := range comparisons {
		c.AddSummaries(os.Stdout, confidence, 1000)
	}

	// Generate some output.  Options include CSV, JSON, PNG, perhaps also PDF and SVG.

	var options benchseries.CsvOptions

	if delta {
		options |= benchseries.CSV_DELTA
	}
	if change {
		options |= benchseries.CSV_CHANGE_HEU | benchseries.CSV_CHANGE_KS
	}
	if values {
		options |= benchseries.CSV_VALUES
	}

	if jsonOut != "" {
		w, err := os.Create(jsonOut)
		if err != nil {
			fail("Could not create JSON output file (flag -jo), %v", err)
		}
		encoder := json.NewEncoder(w)
		encoder.SetIndent("", "\t")
		encoder.Encode(comparisons)
		w.Close()
	}

	if csv {
		for _, comparison := range comparisons {
			comparison.ToCsvBootstrapped(os.Stdout, options, threshold)
		}
	}
	if pngDir != "" || pdfDir != "" || svgDir != "" {
		benchseries.Chart(comparisons, pngDir, pdfDir, svgDir, logScale, threshold, boring)
	}
}

func fail(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	os.Exit(1)
}
func warn(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
}
