// 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"
)

var expectedVarValues = map[string]interface{}{
	`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(t *testing.T, name string, args ...string) {
	cmd := exec.Command(name, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		t.Fatal(err)
	}
}

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

func TestBreakAndEval(t *testing.T) {
	run(t, "go", "build", "-o", proxyBinary, proxySrc)
	defer os.Remove(proxyBinary)

	run(t, "go", "build", "-o", traceeBinary, traceeSrc)
	defer os.Remove(traceeBinary)

	client.OgleproxyCmd = proxyBinary
	var (
		prog program.Program
		err  error
	)
	prog, err = client.Run("localhost", traceeBinary)
	if err != nil {
		log.Fatalf("Run: %v", err)
	}

	_, err = prog.Run()
	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")
		}
	}
}
