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

import (
	"context"
	"fmt"

	"go.fuchsia.dev/tools/lib/logger"
)

// TODO (jakehehrlich): LineSource is now a part of the public interface. This is needed to
// allow for the proper construction of triggers since triggers need to know
// where a triggering element came from. Right now this is just an empty
// interface. It would be nice if the user could do soemthing other than cast this.
type LineSource interface{}

type Process uint64

type DummySource struct{}

type LineHeader interface {
	Present() string
}

type logHeader struct {
	time    float64
	process uint64
	thread  uint64
}

func (l logHeader) Present() string {
	return fmt.Sprintf("[%.3f] %05d.%05d>", l.time, l.process, l.thread)
}

type sysLogHeader struct {
	time    float64
	process uint64
	thread  uint64
	tags    string
	typ     string
}

func (s sysLogHeader) Present() string {
	return fmt.Sprintf("[%012.6f][%d][%d][%s] %s:", s.time, s.process, s.thread, s.tags, s.typ)
}

type LogLine struct {
	lineno uint64
	header LineHeader
	source LineSource
}

type InputLine struct {
	LogLine
	msg string
}

// Later this will be more general.
type Segment struct {
	Mod        uint64 `json:"mod"`
	Vaddr      uint64 `json:"vaddr"`
	Size       uint64 `json:"size"`
	Flags      string `json:"flags"`
	ModRelAddr uint64 `json:"modRelAddr"`
}

type addressInfo struct {
	locs []SourceLocation
	mod  Module
	seg  Segment
	addr uint64
}

type Module struct {
	Name  string `json:"name"`
	Build string `json:"build"`
	Id    uint64 `json:"id"`
}

type OutputLine struct {
	LogLine
	line []Node
}

type missingObjError struct {
	name    string
	buildid string
	err     error
}

func (m *missingObjError) Error() string {
	return fmt.Sprintf("could not find file for module %s with build ID %s: %v", m.name, m.buildid, m.err)
}

type Repository interface {
	GetBuildObject(buildID string) (string, error)
}

// Filter represents the state needed to process a log.
type Filter struct {
	// handles for llvm-symbolizer
	symbolizer Symbolizer
	// Symbolizer context
	symContext        mappingStore
	modules           map[uint64]Module
	modNamesByBuildID map[string]string
	// Symbolizer repository
	repo Repository
}

// TODO (jakehehrlich): Consider making FindInfoForAddress private.

// FindInfoForAddress takes a process an in memory address and converts it to a source location.
func (s *Filter) findInfoForAddress(vaddr uint64) (addressInfo, error) {
	info := addressInfo{addr: vaddr}
	// Sometimes zero will be requested as an address. We should not warn in this case.
	if vaddr == 0 {
		return info, nil
	}
	seg := s.symContext.find(vaddr)
	if seg == nil {
		return info, fmt.Errorf("could not find segment that covers 0x%x", vaddr)
	}
	info.seg = *seg
	if mod, ok := s.modules[info.seg.Mod]; ok {
		info.mod = mod
	} else {
		return info, fmt.Errorf("could not find module for 0x%x", vaddr)
	}
	modRelAddr := vaddr - seg.Vaddr + seg.ModRelAddr
	mod, ok := s.modules[seg.Mod]
	if !ok {
		return info, fmt.Errorf("could not find module with module ID %d", seg.Mod)
	}
	modPath, err := s.repo.GetBuildObject(mod.Build)
	if err != nil {
		out := &missingObjError{mod.Name, mod.Build, err}
		return info, out
	}
	result := <-s.symbolizer.FindSrcLoc(modPath, mod.Build, modRelAddr)
	if result.Err != nil {
		return info, fmt.Errorf("in module %s with build ID %s: %v", mod.Name, mod.Build, result.Err)
	}
	info.locs = result.Locs
	return info, nil
}

// NewFilter creates a new filter
func NewFilter(repo Repository, symbo Symbolizer) *Filter {
	return &Filter{
		modules:           make(map[uint64]Module),
		modNamesByBuildID: make(map[string]string),
		repo:              repo,
		symbolizer:        symbo,
	}
}

// Reset resets the filter so that it can work for a new process
func (s *Filter) reset() {
	s.modules = make(map[uint64]Module)
	s.symContext.clear()
}

// AddModule updates the filter state to inform it of a new module
func (s *Filter) addModule(m Module) error {
	var err error
	// TODO(jakehehrlich): Add check to see if two modules with the same
	// build IDs but different names are added and emit a warning if they
	// are. Keep in mind that the notion of "same name" has to be carefully
	// defined so that cases like <VMO#87378=ld.so.l> and <VMO#87393=ld.so.l>
	// do not trigger the warning.

	// Keep track of modules by build ID.
	s.modNamesByBuildID[m.Build] = m.Name
	s.modules[m.Id] = m
	return err
}

// AddSegment updates the filter state to inform it of a new memory mapped location.
func (s *Filter) addSegment(seg Segment) {
	s.symContext.add(seg)
}

// Start tells the filter to start consuming input and produce output.
func (f *Filter) Start(ctx context.Context, input <-chan InputLine) <-chan OutputLine {
	out := make(chan OutputLine)
	parseLine := GetLineParser()
	go func() {
		for {
			select {
			case <-ctx.Done():
				return
			case elem, ok := <-input:
				if !ok {
					return
				}
				var res OutputLine
				if res.line = parseLine(elem.msg); res.line == nil {
					res.line = []Node{&Text{text: elem.msg}}
				}
				// Update AST with source locations.
				for _, token := range res.line {
					token.Accept(&filterVisitor{filter: f, lineno: elem.lineno, ctx: ctx, source: elem.source})
				}
				res.LogLine = elem.LogLine
				out <- res
			}
		}
	}()
	return out
}

type filterVisitor struct {
	filter *Filter
	lineno uint64
	ctx    context.Context
	source LineSource
}

func (f *filterVisitor) warn(err error) {
	logger.Warningf(f.ctx, "on line %d: %v", f.lineno, err)
}

func (f *filterVisitor) debug(err error) {
	logger.Debugf(f.ctx, "on line %d: %v", f.lineno, err)
}

func (f *filterVisitor) VisitBt(elem *BacktraceElement) {
	info, err := f.filter.findInfoForAddress(elem.vaddr)
	if err != nil {
		// Don't be noisy about missing objects.
		if _, ok := err.(*missingObjError); ok {
			f.debug(err)
		} else {
			f.warn(err)
		}
	}
	elem.info = info
}

func (f *filterVisitor) VisitPc(elem *PCElement) {
	info, err := f.filter.findInfoForAddress(elem.vaddr)
	if err != nil {
		// Don't be noisy about missing objects.
		if _, ok := err.(*missingObjError); !ok {
			f.warn(err)
		}
	}
	elem.info = info
}

func (f *filterVisitor) VisitColor(group *ColorCode) {

}

func (f *filterVisitor) VisitText(_ *Text) {
	// This must be implemented in order to meet the interface but it has no effect.
	// This visitor is supposed to do all of the non-parsing parts of constructing the AST.
	// There is nothing to do for Text however.
}

func (f *filterVisitor) VisitDump(elem *DumpfileElement) {
	// Defensive copies must be made here for two reasons:
	//   1) We don't want the trigger handler to change internal state
	//   2) The trigger handler is allowed to store/process the context
	//      at a later date and we might have modified either of these
	//      in the interim.
	segs := f.filter.symContext.GetSegments()
	mods := []Module{}
	for _, mod := range f.filter.modules {
		mods = append(mods, mod)
	}
	elem.context = &TriggerContext{Source: f.source, Mods: mods, Segs: segs}
}

func (f *filterVisitor) VisitReset(elem *ResetElement) {
	// TODO: Check if Reset had an effect and output that a pid reuse occured.
	f.filter.reset()
}

func (f *filterVisitor) VisitModule(elem *ModuleElement) {
	err := f.filter.addModule(elem.mod)
	if err != nil {
		f.warn(err)
	}
}

func (f *filterVisitor) VisitMapping(elem *MappingElement) {
	f.filter.addSegment(elem.seg)
}
