// processFile processes a single bugreport file, and returns the parsing result as a string.
// Writes csv data to csvWriter if a csv file is specified.
func processFile(filePath string, csvWriter *bufio.Writer, isFirstFile bool) string {
	// Read the whole file
	c, err := ioutil.ReadFile(filePath)
	if err != nil {
		log.Fatal(err)
	}
	br, fname, err := bugreportutils.ExtractBugReport(filePath, c)
	if err != nil {
		log.Fatalf("Error getting file contents: %v", err)
	}
	fmt.Printf("Parsing %s\n", fname)

	writer := ioutil.Discard
	if csvWriter != nil && *summaryFormat == parseutils.FormatTotalTime {
		writer = csvWriter
	}

	pkgs, errs := packageutils.ExtractAppsFromBugReport(br)
	if len(errs) > 0 {
		log.Printf("Errors encountered when getting package list: %v\n", errs)
	}
	upm, errs := parseutils.UIDAndPackageNameMapping(br, pkgs)
	if len(errs) > 0 {
		log.Printf("Errors encountered when generating package mapping: %v\n", errs)
	}
	rep := parseutils.AnalyzeHistory(writer, br, *summaryFormat, upm, *scrubPII)

	// Exclude summaries with no change in battery level
	var a []parseutils.ActivitySummary
	for _, s := range rep.Summaries {
		if s.InitialBatteryLevel != s.FinalBatteryLevel {
			a = append(a, s)
		}
	}

	if rep.TimestampsAltered {
		fmt.Println("Some timestamps were changed while processing the log.")
	}
	if len(rep.Errs) > 0 {
		fmt.Println("Errors encountered:")
		for _, err := range rep.Errs {
			fmt.Println(err.Error())
		}
	}
	fmt.Println("\nNumber of summaries ", len(a), "\n")
	for _, s := range a {
		s.Print(&rep.OutputBuffer)
	}

	// Write the battery level summary csv to the csvFile specified
	if csvWriter != nil && *summaryFormat == parseutils.FormatBatteryLevel {
		// The dimension header line is only written if the file is the first one in the directory.
		parseutils.BatteryLevelSummariesToCSV(csvWriter, &a, isFirstFile)
	}

	return rep.OutputBuffer.String()
}
func analyze(bugReport string, pkgs []*usagepb.PackageInfo) summariesData {
	upm, errs := parseutils.UIDAndPackageNameMapping(bugReport, pkgs)

	var bufTotal, bufLevel bytes.Buffer
	// repTotal contains summaries over discharge intervals
	repTotal := parseutils.AnalyzeHistory(&bufTotal, bugReport, parseutils.FormatTotalTime, upm, false)
	// repLevel contains summaries for each battery level drop.
	// The generated errors would be the exact same as repTotal.Errs so no need to track or add them again.
	parseutils.AnalyzeHistory(&bufLevel, bugReport, parseutils.FormatBatteryLevel, upm, false)

	// Exclude summaries with no change in battery level
	var summariesTotal []parseutils.ActivitySummary
	for _, s := range repTotal.Summaries {
		if s.InitialBatteryLevel != s.FinalBatteryLevel {
			summariesTotal = append(summariesTotal, s)
		}
	}

	errs = append(errs, repTotal.Errs...)
	return summariesData{summariesTotal, bufTotal.String(), bufLevel.String(), repTotal.TimeToDelta, errs, repTotal.Overflow}
}