// Copyright 2018 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 bloaty

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"sort"
	"strings"
	"sync"
)

type bloatyOutput struct {
	data row
	file string
	err  error
}

// TODO(jakehehrlich): Add reading ids.txt to elflib, since there are now three
// different tools that each need to read it for mostly unrelated reasons
func getFiles(idsPath string) ([]string, error) {
	out := []string{}
	idsFile, err := os.Open(idsPath)
	if err != nil {
		return nil, err
	}
	defer idsFile.Close()
	scanner := bufio.NewScanner(idsFile)
	for line := 1; scanner.Scan(); line++ {
		parts := strings.SplitN(scanner.Text(), " ", 2)
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid ids.txt: error on line %d", line)
		}
		out = append(out, parts[1])
	}
	return out, nil
}

func run(bloatyPath, file string, out chan<- bloatyOutput) {
	args := []string{
		"-d", "segments,compileunits,symbols",
		"-s", "file",
		"--tsv",
		"-n", "0",
		file,
	}
	cmd := exec.Command(bloatyPath, args...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		out <- bloatyOutput{err: fmt.Errorf("pipe: %s: %s", file, err)}
		return
	}

	var stderr bytes.Buffer
	cmd.Stderr = &stderr

	if err := cmd.Start(); err != nil {
		out <- bloatyOutput{err: fmt.Errorf("start: %s: %s", file, cmd.Stderr)}
		stdout.Close()
		return
	}

	err = ReadCSV(stdout, out, file)
	if err != nil {
		out <- bloatyOutput{err: fmt.Errorf("csv: %s: %s", file, err)}
		stdout.Close()
		return
	}

	if err := cmd.Wait(); err != nil {
		out <- bloatyOutput{err: fmt.Errorf("wait: %s: %s", file, cmd.Stderr)}
		return
	}
}

func updateSymbol(newSym *row, file string, sym *Symbol) {
	sym.Name = newSym.Symbol
	sym.Vmsz += newSym.Vmsz
	sym.Filesz += newSym.Filesz
	sym.Binaries = append(sym.Binaries, file)
}

func addRowToOutput(r *row, file string, output map[string]*Segment) {
	if _, ok := output[r.Seg]; !ok {
		output[r.Seg] = &Segment{make(map[string]*File)}
	}
	seg := output[r.Seg]

	if _, ok := seg.Files[r.File]; !ok {
		seg.Files[r.File] = &File{Symbols: make(map[string]*Symbol)}
	}
	f := seg.Files[r.File]

	if _, ok := f.Symbols[r.Symbol]; !ok {
		f.Symbols[r.Symbol] = &Symbol{}
	}
	updateSymbol(r, file, f.Symbols[r.Symbol])
	seg.Files[r.File] = f
	output[r.Seg] = seg
}

func getTopN(fileSizes map[string]uint64, topFiles, topSyms uint64, output *map[string]*Segment) {
	// If both topFiles and topSyms are 0, bail early because we're returning everything.
	if topFiles == 0 && topSyms == 0 {
		return
	}
	type sortedFile struct {
		name string
		size uint64
	}

	smallFiles := make(map[string]uint64)
	if topFiles > 0 && topFiles < uint64(len(fileSizes)) {
		var all []struct {
			name string
			size uint64
		}
		for name, size := range fileSizes {
			all = append(all, sortedFile{name, size})
		}
		sort.Slice(all, func(i, j int) bool {
			return all[i].size < all[j].size
		})

		for _, d := range all[:uint64(len(all))-topFiles] {
			smallFiles[d.name] = d.size
		}
	}

	for _, segData := range *output {
		smallFilesSize := uint64(0)
		for file, fileData := range segData.Files {
			smallSyms := Symbol{Name: "all small syms"}
			// If the file labeled a small file, add to small files size and delete the sym data.
			if size, exists := smallFiles[file]; exists {
				smallFilesSize += size
				delete(segData.Files, file)
			} else if topSyms > 0 && topSyms < uint64(len(fileData.Symbols)) {
				var all []*Symbol
				for _, sym := range fileData.Symbols {
					all = append(all, sym)
				}
				sort.Slice(all, func(i, j int) bool {
					return all[i].Filesz < all[j].Filesz
				})

				for _, d := range all[:uint64(len(all))-topSyms] {
					if sym, exists := fileData.Symbols[d.Name]; exists {
						smallSyms.Vmsz += sym.Vmsz
						smallSyms.Filesz += sym.Filesz
						delete(fileData.Symbols, d.Name)
					}
				}
			}

			if topSyms > 0 {
				fileData.Symbols["all small syms"] = &smallSyms
			}
		}

		if topFiles > 0 {
			segData.Files["all small files"] = &File{TotalFilesz: smallFilesSize}
		}
	}
}

// RunBloaty runs bloaty on all files in ids.txt, and returns a mapping of the
// symbols and files by segment.
func RunBloaty(bloatyPath, idsPath string, topFiles, topSyms uint64, jobs int) (map[string]*Segment, error) {
	files, err := getFiles(idsPath)
	if err != nil {
		return nil, err
	}

	var wg sync.WaitGroup
	data := make(chan bloatyOutput)

	// Only allow up to max jobs concurrent executions
	fileBuffer := make(chan string, jobs)
	go func() {
		for _, file := range files {
			fileBuffer <- file
		}
		close(fileBuffer)
	}()

	for file := range fileBuffer {
		wg.Add(1)
		go func(file string) {
			run(bloatyPath, file, data)
			wg.Done()
		}(file)
	}

	go func() {
		wg.Wait()
		close(data)
	}()

	output := make(map[string]*Segment)
	fileSizes := make(map[string]uint64)

	for d := range data {
		if d.err != nil {
			fmt.Printf("%v", d.err)
			continue
		}
		addRowToOutput(&d.data, d.file, output)
		fileSizes[d.data.File] += d.data.Filesz
	}

	getTopN(fileSizes, topFiles, topSyms, &output)
	return output, nil
}
