// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package symbolizer

import (
	"fmt"
	"regexp"
	"sort"
	"strings"
	"testing"

	"github.com/google/pprof/internal/plugin"
	"github.com/google/pprof/internal/proftest"
	"github.com/google/pprof/profile"
)

var testM = []*profile.Mapping{
	{
		ID:    1,
		Start: 0x1000,
		Limit: 0x5000,
		File:  "mapping",
	},
}

var testL = []*profile.Location{
	{
		ID:      1,
		Mapping: testM[0],
		Address: 1000,
	},
	{
		ID:      2,
		Mapping: testM[0],
		Address: 2000,
	},
	{
		ID:      3,
		Mapping: testM[0],
		Address: 3000,
	},
	{
		ID:      4,
		Mapping: testM[0],
		Address: 4000,
	},
	{
		ID:      5,
		Mapping: testM[0],
		Address: 5000,
	},
}

var testProfile = profile.Profile{
	DurationNanos: 10e9,
	SampleType: []*profile.ValueType{
		{Type: "cpu", Unit: "cycles"},
	},
	Sample: []*profile.Sample{
		{
			Location: []*profile.Location{testL[0]},
			Value:    []int64{1},
		},
		{
			Location: []*profile.Location{testL[1], testL[0]},
			Value:    []int64{10},
		},
		{
			Location: []*profile.Location{testL[2], testL[0]},
			Value:    []int64{100},
		},
		{
			Location: []*profile.Location{testL[3], testL[0]},
			Value:    []int64{1},
		},
		{
			Location: []*profile.Location{testL[4], testL[3], testL[0]},
			Value:    []int64{10000},
		},
	},
	Location:   testL,
	Mapping:    testM,
	PeriodType: &profile.ValueType{Type: "cpu", Unit: "milliseconds"},
	Period:     10,
}

func TestSymbolization(t *testing.T) {
	sSym := symbolzSymbolize
	lSym := localSymbolize
	defer func() {
		symbolzSymbolize = sSym
		localSymbolize = lSym
		demangleFunction = Demangle
	}()
	symbolzSymbolize = symbolzMock
	localSymbolize = localMock
	demangleFunction = demangleMock

	type testcase struct {
		mode        string
		wantComment string
	}

	s := Symbolizer{
		Obj: mockObjTool{},
		UI:  &proftest.TestUI{T: t},
	}
	for i, tc := range []testcase{
		{
			"local",
			"local=[]",
		},
		{
			"fastlocal",
			"local=[fast]",
		},
		{
			"remote",
			"symbolz=[]",
		},
		{
			"",
			"local=[]:symbolz=[]",
		},
		{
			"demangle=none",
			"demangle=[none]:force:local=[force]:symbolz=[force]",
		},
		{
			"remote:demangle=full",
			"demangle=[full]:force:symbolz=[force]",
		},
		{
			"local:demangle=templates",
			"demangle=[templates]:force:local=[force]",
		},
		{
			"force:remote",
			"force:symbolz=[force]",
		},
	} {
		prof := testProfile.Copy()
		if err := s.Symbolize(tc.mode, nil, prof); err != nil {
			t.Errorf("symbolize #%d: %v", i, err)
			continue
		}
		sort.Strings(prof.Comments)
		if got, want := strings.Join(prof.Comments, ":"), tc.wantComment; got != want {
			t.Errorf("%q: got %s, want %s", tc.mode, got, want)
			continue
		}
	}
}

func symbolzMock(p *profile.Profile, force bool, sources plugin.MappingSources, syms func(string, string) ([]byte, error), ui plugin.UI) error {
	var args []string
	if force {
		args = append(args, "force")
	}
	p.Comments = append(p.Comments, "symbolz=["+strings.Join(args, ",")+"]")
	return nil
}

func localMock(p *profile.Profile, fast, force bool, obj plugin.ObjTool, ui plugin.UI) error {
	var args []string
	if fast {
		args = append(args, "fast")
	}
	if force {
		args = append(args, "force")
	}
	p.Comments = append(p.Comments, "local=["+strings.Join(args, ",")+"]")
	return nil
}

func demangleMock(p *profile.Profile, force bool, mode string) {
	if force {
		p.Comments = append(p.Comments, "force")
	}
	if mode != "" {
		p.Comments = append(p.Comments, "demangle=["+mode+"]")
	}
}

func TestLocalSymbolization(t *testing.T) {
	prof := testProfile.Copy()

	if prof.HasFunctions() {
		t.Error("unexpected function names")
	}
	if prof.HasFileLines() {
		t.Error("unexpected filenames or line numbers")
	}

	b := mockObjTool{}
	if err := localSymbolize(prof, false, false, b, &proftest.TestUI{T: t}); err != nil {
		t.Fatalf("localSymbolize(): %v", err)
	}

	for _, loc := range prof.Location {
		if err := checkSymbolizedLocation(loc.Address, loc.Line); err != nil {
			t.Errorf("location %d: %v", loc.Address, err)
		}
	}
	if !prof.HasFunctions() {
		t.Error("missing function names")
	}
	if !prof.HasFileLines() {
		t.Error("missing filenames or line numbers")
	}
}

func checkSymbolizedLocation(a uint64, got []profile.Line) error {
	want, ok := mockAddresses[a]
	if !ok {
		return fmt.Errorf("unexpected address")
	}
	if len(want) != len(got) {
		return fmt.Errorf("want len %d, got %d", len(want), len(got))
	}

	for i, w := range want {
		g := got[i]
		if g.Function.Name != w.Func {
			return fmt.Errorf("want function: %q, got %q", w.Func, g.Function.Name)
		}
		if g.Function.Filename != w.File {
			return fmt.Errorf("want filename: %q, got %q", w.File, g.Function.Filename)
		}
		if g.Line != int64(w.Line) {
			return fmt.Errorf("want lineno: %d, got %d", w.Line, g.Line)
		}
	}
	return nil
}

var mockAddresses = map[uint64][]plugin.Frame{
	1000: {frame("fun11", "file11.src", 10)},
	2000: {frame("fun21", "file21.src", 20), frame("fun22", "file22.src", 20)},
	3000: {frame("fun31", "file31.src", 30), frame("fun32", "file32.src", 30), frame("fun33", "file33.src", 30)},
	4000: {frame("fun41", "file41.src", 40), frame("fun42", "file42.src", 40), frame("fun43", "file43.src", 40), frame("fun44", "file44.src", 40)},
	5000: {frame("fun51", "file51.src", 50), frame("fun52", "file52.src", 50), frame("fun53", "file53.src", 50), frame("fun54", "file54.src", 50), frame("fun55", "file55.src", 50)},
}

func frame(fname, file string, line int) plugin.Frame {
	return plugin.Frame{
		Func: fname,
		File: file,
		Line: line}
}

type mockObjTool struct{}

func (mockObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
	return mockObjFile{frames: mockAddresses}, nil
}

func (mockObjTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
	return nil, fmt.Errorf("disassembly not supported")
}

type mockObjFile struct {
	frames map[uint64][]plugin.Frame
}

func (mockObjFile) Name() string {
	return ""
}

func (mockObjFile) Base() uint64 {
	return 0
}

func (mockObjFile) BuildID() string {
	return ""
}

func (mf mockObjFile) SourceLine(addr uint64) ([]plugin.Frame, error) {
	return mf.frames[addr], nil
}

func (mockObjFile) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
	return []*plugin.Sym{}, nil
}

func (mockObjFile) Close() error {
	return nil
}
