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

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"os"

	"fuchsia.googlesource.com/tools/color"
	"fuchsia.googlesource.com/tools/logger"
	"fuchsia.googlesource.com/tools/symbolize"
)

var (
	llvmSymboPath string
	idsPath       string
	colorValue    string
	jsonOutput    string
)

func init() {
	flag.StringVar(&llvmSymboPath, "llvm-symbolizer", "llvm-symbolizer", "path to llvm-symbolizer")
	flag.StringVar(&idsPath, "ids", "", "path to ids.txt")
	flag.StringVar(&colorValue, "color", "auto", "can be `always`, `auto`, or `never`.")
	flag.StringVar(&jsonOutput, "json-output", "", "outputs trigger information to the specified file")
}

func getColor() (color.Color, error) {
	ec := color.EnableColor(colorValue)
	switch ec {
	case color.ColorAlways, color.ColorNever, color.ColorAuto:
		return color.NewColor(ec), nil
	default:
		return nil, fmt.Errorf("invalid color option `%s`, possible values are `always`, `auto`, and `never`", colorValue)
	}
}

type dumpEntry struct {
	Modules  []symbolize.Module  `json:"modules"`
	Segments []symbolize.Segment `json:"segments"`
	Type     string              `json:"type"`
	Name     string              `json:"name"`
}

type dumpHandler struct {
	dumps []dumpEntry
}

func (d *dumpHandler) HandleDump(dump *symbolize.DumpfileElement) {
	triggerCtx := dump.Context()
	d.dumps = append(d.dumps, dumpEntry{
		Modules:  triggerCtx.Mods,
		Segments: triggerCtx.Segs,
		Type:     dump.SinkType(),
		Name:     dump.Name(),
	})
}

func (d *dumpHandler) Write(buf io.Writer) error {
	enc := json.NewEncoder(buf)
	enc.SetIndent("", "  ")
	err := enc.Encode(d.dumps)
	if err != nil {
		return err
	}
	return nil
}

func main() {
	// Parse flags and setup helpers
	flag.Parse()
	painter, err := getColor()
	if err != nil {
		log.Fatal(err)
	}
	var jsonTriggerHandler *dumpHandler
	if jsonOutput != "" {
		jsonTriggerHandler = &dumpHandler{}
	}

	// Setup logger and context
	symbolizeLogger := logger.NewLogger(logger.WarningLevel, painter, os.Stderr, os.Stderr)
	ctx := logger.WithLogger(context.Background(), symbolizeLogger)

	// Construct the nodes of the pipeline
	symbolizer := symbolize.NewLLVMSymbolizer(llvmSymboPath)
	repo := symbolize.NewRepo()
	err = repo.AddSource(symbolize.NewIDsSource(idsPath))
	if err != nil {
		symbolizeLogger.Fatalf("%v", err)
	}
	demuxer := symbolize.NewDemuxer(repo, symbolizer)
	tap := symbolize.NewTriggerTap()
	if jsonTriggerHandler != nil {
		tap.AddHandler(jsonTriggerHandler.HandleDump)
	}
	presenter := symbolize.NewBasicPresenter(os.Stdout, painter.Enabled())

	// Build the pipeline to start presenting.
	err = symbolizer.Start(ctx)
	if err != nil {
		symbolizeLogger.Fatalf("%v", err)
	}
	inputLines := symbolize.StartParsing(ctx, os.Stdin)
	outputLines := demuxer.Start(ctx, inputLines)
	trash := symbolize.ComposePostProcessors(ctx, outputLines,
		tap,
		&symbolize.FilterContextElements{},
		&symbolize.OptimizeColor{},
		symbolize.NewBacktracePresenter(os.Stdout, presenter))
	symbolize.Consume(trash)

	// Once the pipeline has finished output all triggers
	if jsonTriggerHandler != nil {
		file, err := os.Create(jsonOutput)
		if err != nil {
			log.Fatal(err)
		}
		if err := jsonTriggerHandler.Write(file); err != nil {
			log.Fatal(err)
		}
	}
}
