// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Demo program that starts another program and calls Ogle library functions
// to debug it.

package ogler

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"testing"

	"golang.org/x/debug/ogle/program"
	"golang.org/x/debug/ogle/program/client"
	"golang.org/x/debug/ogle/program/local"
)

var expectedVarValues = map[string]interface{}{
	`main.Z_bool_false`: false,
	`main.Z_bool_true`:  true,
	`main.Z_complex128`: complex128(1.987654321 - 2.987654321i),
	`main.Z_complex64`:  complex64(1.54321 + 2.54321i),
	`main.Z_float32`:    float32(1.54321),
	`main.Z_float64`:    float64(1.987654321),
	`main.Z_int16`:      int16(-32321),
	`main.Z_int32`:      int32(-1987654321),
	`main.Z_int64`:      int64(-9012345678987654321),
	`main.Z_int8`:       int8(-121),
	`main.Z_uint16`:     uint16(54321),
	`main.Z_uint32`:     uint32(3217654321),
	`main.Z_uint64`:     uint64(12345678900987654321),
	`main.Z_uint8`:      uint8(231),
}

var expectedVars = map[string]string{
	`main.Z_array`:               `[5]int8{-121, 121, 3, 2, 1}`,
	`main.Z_array_empty`:         `[0]int8{}`,
	`main.Z_bool_false`:          `false`,
	`main.Z_bool_true`:           `true`,
	`main.Z_channel`:             `(chan int 0xX)`,
	`main.Z_channel_buffered`:    `(chan int 0xX [0/10])`,
	`main.Z_channel_nil`:         `(chan int <nil>)`,
	`main.Z_array_of_empties`:    `[2]struct struct {}{struct struct {} {}, (struct struct {} 0xX)}`,
	`main.Z_complex128`:          `(1.987654321-2.987654321i)`,
	`main.Z_complex64`:           `(1.54321+2.54321i)`,
	`main.Z_float32`:             `1.54321`,
	`main.Z_float64`:             `1.987654321`,
	`main.Z_func_int8_r_int8`:    `func(int8, *int8) void @0xX `,
	`main.Z_func_int8_r_pint8`:   `func(int8, **int8) void @0xX `,
	`main.Z_func_bar`:            `func(*main.FooStruct) void @0xX `,
	`main.Z_int`:                 `-21`,
	`main.Z_int16`:               `-32321`,
	`main.Z_int32`:               `-1987654321`,
	`main.Z_int64`:               `-9012345678987654321`,
	`main.Z_int8`:                `-121`,
	`main.Z_interface`:           `("*main.FooStruct", 0xX)`,
	`main.Z_interface_nil`:       `(<nil>, <nil>)`,
	`main.Z_interface_typed_nil`: `("*main.FooStruct", <nil>)`,
	`main.Z_map`:                 `{-21:3.54321}`,
	`main.Z_map_2`:               `{1024:1}`,
	`main.Z_map_empty`:           `{}`,
	`main.Z_map_nil`:             `<nil>`,
	`main.Z_pointer`:             `0xX`,
	`main.Z_pointer_nil`:         `0x0`,
	`main.Z_slice`:               `[]uint8{115, 108, 105, 99, 101}`,
	`main.Z_slice_2`:             `[]int8{-121, 121}`,
	`main.Z_slice_nil`:           `[]uint8{}`,
	`main.Z_string`:              `"I'm a string"`,
	`main.Z_struct`:              `struct main.FooStruct {21, "hi"}`,
	`main.Z_uint`:                `21`,
	`main.Z_uint16`:              `54321`,
	`main.Z_uint32`:              `3217654321`,
	`main.Z_uint64`:              `12345678900987654321`,
	`main.Z_uint8`:               `231`,
	`main.Z_uintptr`:             `21`,
	`main.Z_unsafe_pointer`:      `0xX`,
	`main.Z_unsafe_pointer_nil`:  `0x0`,
}

func isHex(r uint8) bool {
	switch {
	case '0' <= r && r <= '9':
		return true
	case 'a' <= r && r <= 'f':
		return true
	case 'A' <= r && r <= 'F':
		return true
	default:
		return false
	}
}

// Check s matches the pattern in p.
// An 'X' in p greedily matches one or more hex characters in s.
func matches(p, s string) bool {
	j := 0
	for i := 0; i < len(p); i++ {
		if j == len(s) {
			return false
		}
		c := p[i]
		if c == 'X' {
			if !isHex(s[j]) {
				return false
			}
			for j < len(s) && isHex(s[j]) {
				j++
			}
			continue
		}
		if c != s[j] {
			return false
		}
		j++
	}
	return j == len(s)
}

func run(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

const (
	proxySrc     = "golang.org/x/debug/ogle/cmd/ogleproxy"
	proxyBinary  = "./ogleproxy"
	traceeSrc    = "golang.org/x/debug/ogle/demo/tracee"
	traceeBinary = "./tracee"
)

func TestMain(m *testing.M) {
	os.Exit(buildAndRunTests(m))
}

func buildAndRunTests(m *testing.M) int {
	if err := run("go", "build", "-o", proxyBinary, proxySrc); err != nil {
		fmt.Println(err)
		return 1
	}
	client.OgleproxyCmd = proxyBinary
	defer os.Remove(proxyBinary)
	if err := run("go", "build", "-o", traceeBinary, traceeSrc); err != nil {
		fmt.Println(err)
		return 1
	}
	defer os.Remove(traceeBinary)
	return m.Run()
}

func TestLocalProgram(t *testing.T) {
	prog, err := local.New(traceeBinary)
	if err != nil {
		t.Fatal("local.New:", err)
	}
	testProgram(t, prog)
}

func TestRemoteProgram(t *testing.T) {
	prog, err := client.New("localhost", traceeBinary)
	if err != nil {
		t.Fatal("client.New:", err)
	}
	testProgram(t, prog)
}

func testProgram(t *testing.T, prog program.Program) {
	_, err := prog.Run("some", "arguments")
	if err != nil {
		log.Fatalf("Run: %v", err)
	}

	pcs, err := prog.Breakpoint("re:main.foo")
	if err != nil {
		log.Fatalf("Breakpoint: %v", err)
	}
	fmt.Printf("breakpoints set at %x\n", pcs)

	_, err = prog.Resume()
	if err != nil {
		log.Fatalf("Resume: %v", err)
	}

	frames, err := prog.Frames(100)
	if err != nil {
		log.Fatalf("prog.Frames error: %v", err)
	}
	fmt.Printf("%#v\n", frames)

	varnames, err := prog.Eval(`re:main\.Z_.*`)
	if err != nil {
		log.Fatalf("prog.Eval error: %v", err)
	}

	// Evaluate each of the variables found above, and check they match
	// expectedVars.
	seen := make(map[string]bool)
	for _, v := range varnames {
		val, err := prog.Eval("val:" + v)
		if err != nil {
			log.Fatalf("prog.Eval error for %s: %v", v, err)
		} else {
			fmt.Printf("%s = %v\n", v, val)
			if seen[v] {
				log.Fatalf("Repeated variable %s\n", v)
			}
			seen[v] = true
			if len(val) != 1 {
				log.Fatalf("Should be one value for %s\n", v)
			}
			expected, ok := expectedVars[v]
			if !ok {
				log.Fatalf("Unexpected variable %s\n", v)
			} else {
				if !matches(expected, val[0]) {
					log.Fatalf("Expected %s = %s\n", v, expected)
				}
			}
		}
	}
	for v, e := range expectedVars {
		if !seen[v] {
			log.Fatalf("Didn't get %s = %s\n", v, e)
		}
	}

	// Remove the breakpoint at main.foo, set a breakpoint at main.f1 and main.f2,
	// then delete the breakpoint at main.f1.  Resume, then check we stopped at
	// main.f2.
	err = prog.DeleteBreakpoints(pcs)
	if err != nil {
		log.Fatalf("DeleteBreakpoints: %v", err)
	}
	pcs1, err := prog.Breakpoint("re:main.f1")
	if err != nil {
		log.Fatalf("Breakpoint: %v", err)
	}
	pcs2, err := prog.Breakpoint("re:main.f2")
	if err != nil {
		log.Fatalf("Breakpoint: %v", err)
	}
	err = prog.DeleteBreakpoints(pcs1)
	if err != nil {
		log.Fatalf("DeleteBreakpoints: %v", err)
	}
	status, err := prog.Resume()
	if err != nil {
		log.Fatalf("Resume: %v", err)
	}
	ok := false
	for _, pc := range pcs2 {
		if status.PC == pc {
			ok = true
			break
		}
	}
	if !ok {
		t.Errorf("Stopped at %X expected one of %X.", status.PC, pcs2)
	}

	// Check we get the expected results calling VarByName then Value
	// for the variables in expectedVarValues.
	for name, exp := range expectedVarValues {
		if v, err := prog.VarByName(name); err != nil {
			t.Errorf("VarByName(%s): %s", name, err)
		} else if val, err := prog.Value(v); err != nil {
			t.Errorf("Value for %s: %s", name, err)
		} else if val != exp {
			t.Errorf("Value for %s: got %T(%v) want %T(%v)", name, val, val, exp, exp)
		}
	}

	// Check some error cases for VarByName and Value.
	if _, err = prog.VarByName("not a real name"); err == nil {
		t.Error("VarByName for invalid name: expected error")
	}
	if _, err = prog.Value(program.Var{}); err == nil {
		t.Error("Value of invalid var: expected error")
	}
	if v, err := prog.VarByName("main.Z_int16"); err != nil {
		t.Error("VarByName(main.Z_int16) error:", err)
	} else {
		v.Address = 0
		// v now has a valid type but a bad address.
		_, err = prog.Value(v)
		if err == nil {
			t.Error("Value of invalid location: expected error")
		}
	}

	// checkValue tests that we can get a Var for a variable with the given name,
	// that we can then get the value of that Var, and that calling fn for that
	// value succeeds.
	checkValue := func(name string, fn func(val program.Value) error) {
		if v, err := prog.VarByName(name); err != nil {
			t.Errorf("VarByName(%s): %s", name, err)
		} else if val, err := prog.Value(v); err != nil {
			t.Errorf("value for %s: %s", name, err)
		} else if err := fn(val); err != nil {
			t.Errorf("value for %s: %s", name, err)
		}
	}

	checkValue("main.Z_uintptr", func(val program.Value) error {
		if val != uint32(21) && val != uint64(21) {
			// Z_uintptr should be an unsigned integer with size equal to the debugged
			// program's address size.
			return fmt.Errorf("got %T(%v) want 21", val, val)
		}
		return nil
	})

	checkValue("main.Z_int", func(val program.Value) error {
		if val != int32(-21) && val != int64(-21) {
			return fmt.Errorf("got %T(%v) want -21", val, val)
		}
		return nil
	})

	checkValue("main.Z_uint", func(val program.Value) error {
		if val != uint32(21) && val != uint64(21) {
			return fmt.Errorf("got %T(%v) want 21", val, val)
		}
		return nil
	})

	checkValue("main.Z_pointer", func(val program.Value) error {
		if _, ok := val.(program.Pointer); !ok {
			return fmt.Errorf("got %T(%v) expected Pointer", val, val)
		}
		return nil
	})

	checkValue("main.Z_pointer_nil", func(val program.Value) error {
		if p, ok := val.(program.Pointer); !ok {
			return fmt.Errorf("got %T(%v) expected Pointer", val, val)
		} else if p.Address != 0 {
			return fmt.Errorf("got %T(%v) expected nil pointer", val, val)
		}
		return nil
	})

	checkValue("main.Z_array", func(val program.Value) error {
		a, ok := val.(program.Array)
		if !ok {
			return fmt.Errorf("got %T(%v) expected Array", val, val)
		}
		if a.Len() != 5 {
			return fmt.Errorf("got array length %d expected 5", a.Len())
		}
		expected := [5]int8{-121, 121, 3, 2, 1}
		for i := uint64(0); i < 5; i++ {
			if v, err := prog.Value(a.Element(i)); err != nil {
				return fmt.Errorf("reading element %d: %s", i, err)
			} else if v != expected[i] {
				return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i])
			}
		}
		return nil
	})
}
