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

import (
	"fmt"
	"io/ioutil"
	"testing"
)

const (
	ids = `0071116f87e52dab0c21bd1cabc590fab5b06348 /out/libc.so
01885627175ee9996b08af6c64c95a6e30787269 /out/libpc-ps2.so
`
)

func WriteTempIdsTxt() (string, error) {
	idsPath, err := ioutil.TempFile("", "ids")
	if err != nil {
		return "", err
	}
	fmt.Fprintf(idsPath, ids)
	idsPath.Close()
	return idsPath.Name(), nil
}

func TestGetFiles(t *testing.T) {
	idsPath, errIds := WriteTempIdsTxt()
	if errIds != nil {
		t.Fatal(errIds)
	}

	actual, errConfig := getFiles(idsPath)
	if errConfig != nil {
		t.Fatal(errConfig)
	}

	expected := []string{"/out/libc.so", "/out/libpc-ps2.so"}

	if len(actual) != len(expected) {
		t.Fatalf("In TestGenConfig, expected \n%s but got \n%s", expected, actual)
	}

	for i, val := range expected {
		if actual[i] != val {
			t.Fatalf("In TestGenConfig, expected \n%s but got \n%s", expected, actual)
		}
	}
}

func TestGetTopNFiles(t *testing.T) {
	input := map[string]*Segment{
		"LOAD [R]": {
			Files: map[string]*File{
				"file.c": {
					TotalFilesz: 14,
					Symbols: map[string]*Symbol{
						"ecm_bind": {
							Name:     "ecm_bind",
							Vmsz:     14,
							Filesz:   14,
							Binaries: []string{"lib.so"},
						},
					},
				},
				"different.c": {
					TotalFilesz: 5,
					Symbols: map[string]*Symbol{
						"ecm_bind": {
							Name:     "ecm_bind",
							Vmsz:     23,
							Filesz:   5,
							Binaries: []string{"lib.so"},
						},
					},
				},
			},
		},
		"LOAD [RX]": {
			Files: map[string]*File{
				"other.c": {
					TotalFilesz: 1,
					Symbols: map[string]*Symbol{
						"ecm_bind": {
							Name:     "ecm_bind",
							Vmsz:     1,
							Filesz:   1,
							Binaries: []string{"lib.so"},
						},
					},
				},
				"test.c": {
					TotalFilesz: 4,
					Symbols: map[string]*Symbol{
						"test": {
							Name:     "test",
							Vmsz:     4,
							Filesz:   4,
							Binaries: []string{"lib.so"},
						},
					},
				},
			},
		},
	}

	fileSizes := map[string]uint64{
		"file.c":      14,
		"different.c": 5,
		"other.c":     1,
		"test.c":      4,
	}

	getTopN(fileSizes, 1, 0, &input)
	if len(input) != 2 {
		t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input)
	}

	if _, ok := input["LOAD [R]"]; !ok {
		t.Fatalf("In TestGetTopN, missing LOAD [R]: \n%+v", input)
	}

	if len(input["LOAD [R]"].Files) != 2 {
		t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input["LOAD [R]"].Files)
	}

	if val, ok := input["LOAD [R]"].Files["file.c"]; !ok {
		t.Fatalf("In TestGetTopN, missing file.c: \n%+v", input["LOAD [R]"].Files)
	} else if val.TotalFilesz != 14 {
		t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val)
	}

	if val, ok := input["LOAD [R]"].Files["all small files"]; !ok {
		t.Fatalf("In TestGetTopN, missing all small files: \n%+v", input["LOAD [R]"].Files)
	} else if val.TotalFilesz != 5 {
		t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val)
	}

	if _, ok := input["LOAD [RX]"]; !ok {
		t.Fatalf("In TestGetTopN, missing LOAD [RX]: \n%+v", input)
	}

	if len(input["LOAD [RX]"].Files) != 1 {
		t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input["LOAD [R]"].Files)
	}

	if val, ok := input["LOAD [RX]"].Files["all small files"]; !ok {
		t.Fatalf("In TestGetTopN, missing all small files: \n%+v", input["LOAD [R]"].Files)
	} else if val.TotalFilesz != 5 {
		t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val)
	}
}

func TestGetTopNSymbols(t *testing.T) {
	input := map[string]*Segment{
		"LOAD [R]": {
			Files: map[string]*File{
				"file.c": {
					TotalFilesz: 14,
					Symbols: map[string]*Symbol{
						"ecm_bind": {
							Name:     "ecm_bind",
							Vmsz:     14,
							Filesz:   14,
							Binaries: []string{"lib.so"},
						},
						"test": {
							Name:     "test",
							Vmsz:     23,
							Filesz:   5,
							Binaries: []string{"lib.so"},
						},
						"other": {
							Name:     "other",
							Vmsz:     5,
							Filesz:   5,
							Binaries: []string{"lib.so"},
						},
					},
				},
			},
		},
	}

	fileSizes := map[string]uint64{
		"file.c":      14,
		"different.c": 5,
		"other.c":     1,
		"test.c":      4,
	}

	getTopN(fileSizes, 0, 1, &input)
	if len(input) != 1 {
		t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input)
	}

	if _, ok := input["LOAD [R]"]; !ok {
		t.Fatalf("In TestGetTopNSymbols, missing LOAD [R]: \n%+v", input)
	}

	if len(input["LOAD [R]"].Files) != 1 {
		t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input["LOAD [R]"].Files)
	}

	if val, ok := input["LOAD [R]"].Files["file.c"]; !ok {
		t.Fatalf("In TestGetTopNSymbols, missing file.c: \n%+v", input["LOAD [R]"].Files)
	} else if val.TotalFilesz != 14 {
		t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val)
	}

	if len(input["LOAD [R]"].Files["file.c"].Symbols) != 2 {
		t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input["LOAD [R]"].Files["file.c"].Symbols)
	}

	if val, ok := input["LOAD [R]"].Files["file.c"].Symbols["ecm_bind"]; !ok {
		t.Fatalf("In TestGetTopNSymbols, missing ecm_bind: \n%+v", input["LOAD [R]"].Files)
	} else if val.Filesz != 14 {
		t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val)
	}

	if val, ok := input["LOAD [R]"].Files["file.c"].Symbols["all small syms"]; !ok {
		t.Fatalf("In TestGetTopNSymbols, missing ecm_bind: \n%+v", input["LOAD [R]"].Files["file.c"].Symbols["all small syms"])
	} else if val.Filesz != 10 {
		t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val)
	}
}

func TestAddRowToOutput(t *testing.T) {
	rows := []row{
		{"ecm_bind", "other.c", "LOAD [RX]", 7, 7},
		{"test", "other.c", "LOAD [RX]", 12, 2},
		{"ecm_bind", "other.c", "LOAD [R]", 23, 5},
		{"ecm_bind", "file.c", "LOAD [R]", 3, 3},
	}

	actual := make(map[string]*Segment)
	for _, row := range rows {
		addRowToOutput(&row, row.File, actual)
	}

	// {"ecm_bind", "other.c", "LOAD [RX]", 7, 7},
	if _, ok := actual["LOAD [RX]"]; !ok {
		t.Fatalf("In TestAddRowToOutput, got \n%+v", actual)
	}
	if _, ok := actual["LOAD [RX]"].Files["other.c"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c")
	}
	if val, ok := actual["LOAD [RX]"].Files["other.c"].Symbols["ecm_bind"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c ecm_bind")
	} else if val.Name != "ecm_bind" || val.Vmsz != 7 || val.Filesz != 7 {
		t.Fatalf("In TestAddRowToOutput, got \n%+v", val)
	}

	// {"test", "other.c", "LOAD [RX]", 12, 2},
	if val, ok := actual["LOAD [RX]"].Files["other.c"].Symbols["test"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c test")
	} else if val.Name != "test" || val.Vmsz != 12 || val.Filesz != 2 {
		t.Fatalf("In TestAddRowToOutput, got \n%+v", val)
	}

	// {"ecm_bind", "other.c", "LOAD [R]", 23, 5},
	if _, ok := actual["LOAD [R]"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[R]")
	}
	if _, ok := actual["LOAD [R]"].Files["other.c"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[R]:other.c")
	}
	if val, ok := actual["LOAD [R]"].Files["other.c"].Symbols["ecm_bind"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[R] other.c ecm_bind")
	} else if val.Name != "ecm_bind" || val.Vmsz != 23 || val.Filesz != 5 {
		t.Fatalf("In TestAddRowToOutput, got \n%+v", val)
	}

	// {"ecm_bind", "file.c", "LOAD [R]", 3, 3},
	if _, ok := actual["LOAD [R]"].Files["file.c"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[R] file.c")
	}
	if val, ok := actual["LOAD [R]"].Files["file.c"].Symbols["ecm_bind"]; !ok {
		t.Fatalf("In TestAddRowToOutput, missing LOAD[R] file.c ecm_bind")
	} else if val.Name != "ecm_bind" || val.Vmsz != 3 || val.Filesz != 3 {
		t.Fatalf("In TestAddRowToOutput, got \n%+v", val)
	}
}
