// Copyright 2017 The Fuchsia 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 (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"

	"fuchsia.googlesource.com/testing/catapult"
	schema "fuchsia.googlesource.com/testing/perf/schema/v1"
	"github.com/google/subcommands"
)

type MakeHistogramCommand struct{}

func (*MakeHistogramCommand) Name() string {
	return "make_histogram"
}

func (*MakeHistogramCommand) Usage() string {
	return "make_histogram [input_file]"
}

func (*MakeHistogramCommand) Synopsis() string {
	return "Converts performance test output to a catapult HistogramSet"
}

func (*MakeHistogramCommand) SetFlags(flags *flag.FlagSet) {}

// Execute Converts performance test output to a catapult HistogramSet
// The histogram set created by this command does not contain the necessary
// diagnostics for sending to catapult.  To add these diagnostics, use:
//
// 	$ catapult add_diagnostics ....
//
// See https://github.com/catapult-project/catapult/blob/master/docs/histogram-set-json-format.md
func (*MakeHistogramCommand) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
	var variants struct {
		Variants []schema.Variant `json:"variants"`
	}

	inputFile := f.Arg(0)
	blob, err := ioutil.ReadFile(inputFile)
	if err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	if err := json.Unmarshal(blob, &variants); err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	histogramSet := catapult.HistogramSet{}
	histograms := catapult.ConvertVariantsToHistograms(variants.Variants)
	// Track whether any single Histogram addition failed. We do this instead of
	// exiting after a single error to expose as many errors as possible.
	anyAddFailed := false
	for _, histogram := range histograms {
		if err := histogramSet.AddHistogram(histogram); err != nil {
			log.Println(err)
			anyAddFailed = true

		}
	}
	if anyAddFailed {
		return subcommands.ExitFailure
	}

	js, err := json.Marshal(&histogramSet)
	if err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	fmt.Println(string(js))
	return subcommands.ExitSuccess
}
