// 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"
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
)

type mockModule struct {
	name      string
	addr2line map[uint64][]SourceLocation
}

type mockSymbolizer struct {
	modules map[string]mockModule
}

func newMockSymbolizer(modules []mockModule) Symbolizer {
	var out mockSymbolizer
	out.modules = make(map[string]mockModule)
	for _, mod := range modules {
		out.modules[mod.name] = mod
	}
	return &out
}

func (s *mockSymbolizer) FindSrcLoc(file, build string, modRelAddr uint64) <-chan LLVMSymbolizeResult {
	out := make(chan LLVMSymbolizeResult, 1)
	if mod, ok := s.modules[file]; ok {
		if locs, ok := mod.addr2line[modRelAddr]; ok {
			out <- LLVMSymbolizeResult{locs, nil}
		} else {
			out <- LLVMSymbolizeResult{nil, fmt.Errorf("0x%x was not a valid address in %s", modRelAddr, file)}
		}
	} else {
		out <- LLVMSymbolizeResult{nil, fmt.Errorf("%s could not be found", file)}
	}
	return out
}

type symbolizerRepo struct {
	builds map[string]string
}

func TestBasic(t *testing.T) {
	// mock the input and outputs of llvm-symbolizer
	symbo := newMockSymbolizer([]mockModule{
		{getTestdataPath("libc.elf"), map[uint64][]SourceLocation{
			0x429c0: {{NewOptStr("atan2.c"), 49, NewOptStr("atan2")}, {NewOptStr("math.h"), 51, NewOptStr("__DOUBLE_FLOAT")}},
			0x43680: {{NewOptStr("pow.c"), 23, NewOptStr("pow")}},
			0x44987: {{NewOptStr("memcpy.c"), 76, NewOptStr("memcpy")}},
		}},
		{getTestdataPath("libcrypto.elf"), map[uint64][]SourceLocation{
			0x81000: {{NewOptStr("rsa.c"), 101, NewOptStr("mod_exp")}},
			0x82000: {{NewOptStr("aes.c"), 17, NewOptStr("gf256_mul")}},
			0x83000: {{NewOptStr("aes.c"), 560, NewOptStr("gf256_div")}},
		}},
	})
	// Get a line parser
	parseLine := GetLineParser()

	// make an actual filter using those two mock objects
	filter := NewFilter(testBinaries, symbo)

	// parse some example lines
	err := filter.addModule(Module{"libc.elf", "4fcb712aa6387724a9f465a32cd8c14b", 1})
	if err != nil {
		t.Fatal(err)
	}
	err = filter.addModule(Module{"libcrypto.elf", "12ef5c50b3ed3599c07c02d4509311be", 2})
	if err != nil {
		t.Fatal(err)
	}
	filter.addSegment(Segment{1, 0x12345000, 849596, "rx", 0x0})
	filter.addSegment(Segment{2, 0x23456000, 539776, "rx", 0x80000})
	line := parseLine("\033[1m Error at {{{pc:0x123879c0}}}")
	// print out a more precise form
	for _, token := range line {
		token.Accept(&filterVisitor{filter, 1, context.Background(), DummySource{}})
	}
	json, err := GetLineJson(line)
	if err != nil {
		t.Fatalf("json did not parse correctly: %v", err)
	}

	expectedJson := []byte(`[
    {"type": "color", "color": 1},
    {"type": "text", "text": " Error at "},
    {"type": "pc", "vaddr": 305691072, "file": "atan2.c",
     "line": 49, "function": "atan2"}
  ]`)

	if !EqualJson(json, expectedJson) {
		t.Error("expected", expectedJson, "got", json)
	}
}

func TestMalformed(t *testing.T) {
	parseLine := GetLineParser()
	// Parse a bad line
	line := parseLine("\033[1m Error at {{{pc:0x123879c0")
	// Malformed lines should still parse
	if line == nil {
		t.Error("expected", "not nil", "got", line)
	}
}

func EqualJson(a, b []byte) bool {
	var j1, j2 interface{}
	err := json.Unmarshal(a, &j1)
	if err != nil {
		panic(err.Error())
	}
	err = json.Unmarshal(b, &j2)
	if err != nil {
		panic(err.Error())
	}
	return reflect.DeepEqual(j1, j2)
}

func TestBacktrace(t *testing.T) {
	parseLine := GetLineParser()
	line := parseLine("Error at {{{bt:0:0x12389988}}}")

	if line == nil {
		t.Error("got", nil, "expected", "not nil")
		return
	}

	// mock the input and outputs of llvm-symbolizer
	symbo := newMockSymbolizer([]mockModule{
		{getTestdataPath("libc.elf"), map[uint64][]SourceLocation{
			0x44988: {{NewOptStr("duff.h"), 64, NewOptStr("duffcopy")}, {NewOptStr("memcpy.c"), 76, NewOptStr("memcpy")}},
		}},
	})

	// make an actual filter using those two mock objects
	filter := NewFilter(testBinaries, symbo)

	// add some context
	err := filter.addModule(Module{"libc.so", "4fcb712aa6387724a9f465a32cd8c14b", 1})
	if err != nil {
		t.Fatal(err)
	}
	filter.addSegment(Segment{1, 0x12345000, 849596, "rx", 0x0})
	for _, token := range line {
		token.Accept(&filterVisitor{filter, 1, context.Background(), DummySource{}})
	}

	json, err := GetLineJson(line)
	if err != nil {
		t.Error("json did not parse correctly", err)
	}

	expectedJson := []byte(`[
    {"type": "text", "text": "Error at "},
    {"type": "bt", "vaddr": 305699208, "num": 0, "locs":[
      {"line": 64, "function": "duffcopy", "file": "duff.h"},
      {"line": 76, "function": "memcpy", "file": "memcpy.c"}
    ]}
  ]`)

	if !EqualJson(json, expectedJson) {
		t.Error("unexpected json output", "got", string(json), "expected", string(expectedJson))
	}
}

func TestReset(t *testing.T) {
	parseLine := GetLineParser()
	line := parseLine("{{{reset}}}")

	json, err := GetLineJson(line)
	if err != nil {
		t.Error("json did not parse correctly", err)
	}

	expectedJson := []byte(`[{"type":"reset"}]`)
	if !EqualJson(json, expectedJson) {
		t.Error("unexpected json output", "got", string(json), "expected", string(expectedJson))
	}

	// mock the input and outputs of llvm-symbolizer
	symbo := newMockSymbolizer([]mockModule{
		{getTestdataPath("libc.elf"), map[uint64][]SourceLocation{
			0x44987: {{NewOptStr("memcpy.c"), 76, NewOptStr("memcpy")}},
		}},
	})

	// make an actual filter using those two mock objects
	filter := NewFilter(testBinaries, symbo)

	// add some context
	mod := Module{"libc.so", "4fcb712aa6387724a9f465a32cd8c14b", 1}
	err = filter.addModule(mod)
	if err != nil {
		t.Fatal(err)
	}
	seg := Segment{1, 0x12345000, 849596, "rx", 0x0}
	filter.addSegment(seg)

	addr := uint64(0x12389987)

	if info, err := filter.findInfoForAddress(addr); err != nil {
		t.Error("expected", nil, "got", err)
		if len(info.locs) != 1 {
			t.Error("expected", 1, "source location but got", len(info.locs))
		} else {
			loc := SourceLocation{NewOptStr("memcpy.c"), 76, NewOptStr("memcpy")}
			if info.locs[0] != loc {
				t.Error("expected", loc, "got", info.locs[0])
			}
		}
		if info.mod != mod {
			t.Error("expected", mod, "got", info.mod)
		}
		if info.seg != seg {
			t.Error("expected", seg, "got", info.seg)
		}
		if info.addr != addr {
			t.Error("expected", addr, "got", info.addr)
		}
	}

	// now forget the context
	for _, token := range line {
		token.Accept(&filterVisitor{filter, 1, context.Background(), DummySource{}})
	}

	if _, err := filter.findInfoForAddress(addr); err == nil {
		t.Error("expected non-nil error but got", err)
	}
}
