// 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/fuchsia/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 {
	uptime   float64 // Device uptime, in seconds.
	datetime string  // Absolute UTC timestamp.
	process  uint64
	thread   uint64
	tags     string
	typ      string
}

func (s sysLogHeader) Present() string {
	ts := s.datetime
	if ts == "" {
		ts = fmt.Sprintf("%012.6f", s.uptime)
	}
	return fmt.Sprintf("[%s][%d][%d][%s] %s:", ts, 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:"mod_rel_addr"`
}

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)
}

// 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
	}
	defer modPath.Close()
	result := <-s.symbolizer.FindSrcLoc(modPath.String(), 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)
}
